I've been trying to track down the following issue in a Winforms application:
The SynchronizationContext.Current
is null in a task's continuation (i.e. .ContinueWith
) which is run on the main thread (I expect the the current synchronization context to be System.Windows.Forms.WindowsFormsSynchronizationContext
).
Here's the Winforms code demonstrating the issue:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TaskScheduler ts = TaskScheduler.FromCurrentSynchronizationContext(); // Get the UI task scheduler
// This line is required to see the issue (Removing this causes the problem to go away), since it changes the codeflow in
// \SymbolCache\src\source\.NET\4\DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\Threading\ExecutionContext.cs\1305376\ExecutionContext.cs
// at line 435
System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");
var task = Task.Factory.StartNew(() => { });
var cont = task.ContinueWith(MyContinueWith, CancellationToken.None, TaskContinuationOptions.None, ts);
System.Diagnostics.Trace.CorrelationManager.StopLogicalOperation();
}
void MyContinueWith(Task t)
{
if (SynchronizationContext.Current == null) // The current SynchronizationContext shouldn't be null here, but it is.
MessageBox.Show("SynchronizationContext.Current is null");
}
}
}
This is an issue for me since I attempt to use BackgroundWorker
from the continuation, and the BackgroundWorker will use the current SynchronizationContext for its events RunWorkerCompleted
and ProgressChanged
. Since the current SynchronizationContext is null when I kick off the BackgroundWorker, the events don't run on the main ui thread as I intend.
My question:
Is this a bug in Microsoft's code, or have I made a mistake somewhere?
Additional info:
- I'm using .Net 4.0 (I haven't yet tried this on .NET 4.5 RC)
- I can reproduce this on both Debug/Release on any of x86/x64/Any CPU (on an x64 machine).
- It reproduces consistently (I'd be interested if anyone can't reproduce it).
- I have legacy code that uses the BackgroundWorker--so I can't easily change over to not using BackgroundWorker
- I've confirmed that the code in
MyContinueWith
is running on the main ui thread. - I don't know precisely why the
StartLogicalOperation
call helps cause the issue, that's just what I narrowed it down to in my application.