К сожалению, текущий планировщик задач, когда вы запускаете продолжение, становится настройкой SynchronizationContextTaskScheduler
вашей TaskScheduler.FromCurrentSynchronizationContext
.
Это обсуждается в этой ошибке подключения - и было написано таким образом по проекту в .NET 4. Однако я согласен, что поведение оставляет желать лучшегоздесь нужно.
Вы можете обойти это, взяв «фоновый» планировщик в своем конструкторе и используя его:
TaskScheduler _UI;
// Store the default scheduler up front
TaskScheduler _backgroundScheduler = TaskScheduler.Default;
public MainWindow()
{
InitializeComponent();
_UI = TaskScheduler.FromCurrentSynchronizationContext();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
Как только вы это сделаете, вы можете легко запланировать свой «фон»"задача соответственно:
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
//Expected: Worker thread
//Found: Worker thread
DoSomething();
})
.ContinueWith(t =>
{
//Expected: Main thread
//Found: Main thread
DoSomething();
// Use the _backgroundScheduler here
Task.Factory.StartNew(() =>
{
DoSomething();
}, CancellationToken.None, TaskCreationOptions.None, _backgroundScheduler);
}, _UI);
}
Кроме того, в этом случае, поскольку ваша операция заканчивается, вы можете просто поместить ее в свое собственное продолжение и получить желаемое поведение.Это, однако, не решение общего назначения, но оно работает в данном случае :
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
//Expected: Worker thread
//Found: Worker thread
DoSomething();
})
.ContinueWith(t =>
{
//Expected: Main thread
//Found: Main thread
DoSomething();
}, _UI)
.ContinueWith(t =>
{
//Expected: Worker thread
//Found: Is now worker thread
DoSomething();
});
}