Я пытаюсь найти следующую проблему в приложении Winforms: SynchronizationContext.Current
имеет значение null в продолжении задачи (т.е. .ContinueWith
), который запускается в основном потоке (я ожидаю, что текущий контекст синхронизации будет System.Windows.Forms.WindowsFormsSynchronizationContext
).
Здесь код Winforms демонстрирует проблему:
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");
}
}
}
Это проблема для меня, поскольку я пытаюсь использовать BackgroundWorker
из продолжения, а BackgroundWorker будет использовать текущий SynchronizationContext для своих событий RunWorkerCompleted
и ProgressChanged
. Поскольку текущий SynchronizationContext имеет значение null, когда я запускаю BackgroundWorker, события не запускаются в основном потоке ui, как я предполагаю.
Мой вопрос:
Это ошибка в коде Microsoft, или я где-то ошибся?
Дополнительная информация:
- Я использую .Net 4.0 (я еще не пробовал это на .NET 4.5 RC)
- Я могу воспроизвести это как в Debug/Release на любом из x86/x64/Any CPU (на машине x64).
- Он воспроизводится последовательно (мне было бы интересно, если кто-то не сможет воспроизвести его).
- У меня есть устаревший код, который использует BackgroundWorker, поэтому я не могу легко перейти на использование BackgroundWorker
- Я подтвердил, что код в
MyContinueWith
запущен в основном потоке ui. - Я не знаю точно, почему вызов
StartLogicalOperation
помогает вызвать проблему, именно то, что я сузил ее в своем приложении.