SynchronizationContext.Current имеет значение null в продолжении основного потока пользовательского интерфейса

. Я пытался отследить следующую проблему в приложении 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, события не запускаются в основном потоке пользовательского интерфейса, как я предполагал.

Мой вопрос:
Это ошибка в коде Microsoft, или я где-то ошибся?

Дополнительная информация:

  • Я использую.Net 4.0 (. Я еще не пробовал это на.NET 4.5 RC )
  • . Я могу воспроизвести это как при отладке, так и при выпуске на любом из x86/x64/любом процессоре (на машине x64 ).
  • Он воспроизводит последовательно (Мне было бы интересно, если бы кто-нибудь не смог воспроизвести его ).
  • У меня есть устаревший код, который использует BackgroundWorker --, поэтому я не могу легко отказаться от использования BackgroundWorker
  • . Я подтвердил, что код в MyContinueWithвыполняется в основном потоке пользовательского интерфейса.
  • Я не знаю точно, почему вызов StartLogicalOperationпомогает вызвать проблему, это то, к чему я сузил его в своем приложении.
21
задан Matt Smith 15 April 2013 в 01:35
поделиться