Task.ContinueWith 来自调用线程
Task.ContinueWith from calling thread
我正在尝试从创建任务的线程(不是 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 从执行实际任务的线程执行,我希望它从创建任务的线程执行,在本例中为 1。
谢谢
您可以使用 TaskContinuationOptions.ExecuteSynchronously
:
ContinueWith(() => { ... }, TaskContinuationOptions.ExecuteSynchronously);
ExecuteSynchronously
告诉它 try 和 运行 在上次执行先行任务的任何线程上继续。在 Task.Factory.StartNew
调用后继续执行的情况下,该线程将是线程池线程。
但是您必须注意这只是一个提示,框架不会总是满足您的请求。所以你不应该构建你的代码,以至于运行在同一个线程上成为必要。
SynchronizationContext class 使用线程池。
如果您需要单线程同步上下文,那么您应该使用 DispatcherSynchronizationContext、WindowsFormsSynchronizationContext 或根据您的需要编写您自己的同步上下文。
我正在尝试从创建任务的线程(不是 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 从执行实际任务的线程执行,我希望它从创建任务的线程执行,在本例中为 1。
谢谢
您可以使用 TaskContinuationOptions.ExecuteSynchronously
:
ContinueWith(() => { ... }, TaskContinuationOptions.ExecuteSynchronously);
ExecuteSynchronously
告诉它 try 和 运行 在上次执行先行任务的任何线程上继续。在 Task.Factory.StartNew
调用后继续执行的情况下,该线程将是线程池线程。
但是您必须注意这只是一个提示,框架不会总是满足您的请求。所以你不应该构建你的代码,以至于运行在同一个线程上成为必要。
SynchronizationContext class 使用线程池。 如果您需要单线程同步上下文,那么您应该使用 DispatcherSynchronizationContext、WindowsFormsSynchronizationContext 或根据您的需要编写您自己的同步上下文。