Task.ContinueWith来自调用线程

时间:2016-03-25 11:28:27

标签: c# multithreading asynchronous task-parallel-library

我正在尝试从创建任务的线程(不是GUI线程)中执行ContinueWith中的Func。我试过这段代码:

SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());

var scheduler = TaskScheduler.Current.FromCurrentSynchronizationContext();
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
var t = Task.Factory.StartNew(() =>
{
    Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
})
.ContinueWith(
    _ => Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId),
    // Specify where to execute the continuation
    scheduler
);

t.Wait();

但调用者线程和.ContinueWith线程不同。知道为什么吗? 我得到以下结果:

  

1 3 3

看起来传递调度程序会导致ContinueWith从正在执行实际Task的线程执行,我希望它从创建Task的线程执行,在本例中为1。

由于

2 个答案:

答案 0 :(得分:2)

您可以使用TaskContinuationOptions.ExecuteSynchronously

ContinueWith(() => { ... }, TaskContinuationOptions.ExecuteSynchronously);

ExecuteSynchronously告诉它尝试并在上次执行前期任务的任何线程上运行continuation。如果在Task.Factory.StartNew调用之后继续执行,该线程将成为线程池线程。

但是你必须注意这只是一个提示,框架并不总是尊重你的请求。因此,您不应该构造代码,以便在同一个线程上运行成为必需。

答案 1 :(得分:1)

SynchronizationContext 类使用ThreadPool。 如果您需要单线程同步上下文,则应使用 DispatcherSynchronizationContext WindowsFormsSynchronizationContext 或编写您自己的同步上下文,该上下文将根据您的需要工作。