C# Task.ContinueWith来自调用线程

C# Task.ContinueWith来自调用线程,c#,multithreading,asynchronous,task-parallel-library,C#,Multithreading,Asynchronous,Task Parallel Library,我试图从创建任务的线程(不是GUI线程)继续执行Func。我尝试了以下代码: SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); var scheduler = TaskScheduler.Current.FromCurrentSynchronizationContext(); Console.WriteLine(System.Threading.Thread.CurrentThread

我试图从创建任务的线程(不是GUI线程)继续执行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线程不同。知道为什么吗? 我得到以下结果:

13

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


谢谢

您可以使用
任务继续选项。同步执行

ContinueWith(() => { ... }, TaskContinuationOptions.ExecuteSynchronously);
ExecuteSynchronously
告诉它尝试并在上次执行先行任务的线程上运行continuation。如果在
Task.Factory.StartNew
调用之后执行continuation,则该线程将是线程池线程


但是您必须注意这仅仅是一个提示,框架不会始终满足您的请求。因此,您不应该对代码进行结构化,以便必须在同一线程上运行。

您可以使用
TaskContinuationOptions。同步执行

ContinueWith(() => { ... }, TaskContinuationOptions.ExecuteSynchronously);
ExecuteSynchronously
告诉它尝试并在上次执行先行任务的线程上运行continuation。如果在
Task.Factory.StartNew
调用之后执行continuation,则该线程将是线程池线程


但是您必须注意这仅仅是一个提示,框架不会始终满足您的请求。因此,您不应该对代码进行结构化,以便在同一线程上运行成为必要。

同步上下文类使用线程池。
如果您需要单线程同步上下文,那么您应该使用DispatchersSynchronizationContext、WindowsFormsSynchronizationContext或编写您自己的同步上下文,这些上下文将根据您的需要工作。

SynchronizationContext类使用线程池。
如果需要单线程同步上下文,则应使用DispatchersSynchronizationContextWindowsFormsSynchronizationContext或编写自己的同步上下文,以根据需要工作。

是的,问题是我需要异步执行它。我没有很多选择,我正在维护一些遗留代码:(@Davita查看编辑。
ExecuteSynchronously
并不意味着它是同步运行的。正如我所说,这只是一个提示,因为你显式地给它一个调度程序,那么调度程序决定执行它的线程。我相信当你提供一个调度程序时,你想做的事情是做不到的。我没有注意到你在上使用调度程序是否有一个原因让您首先提供该计划程序(现在没有同步上下文)?我认为OP不希望在与先行任务相同的线程上安排继续,他希望它从创建该任务的线程执行。是的,问题是我需要异步执行。我没有很多选择,我正在维护一些遗留代码:(@Davita查看编辑。
ExecuteSynchronously
并不意味着它是同步运行的。正如我所说,这只是一个提示,因为你显式地给它一个调度程序,那么调度程序决定执行它的线程。我相信当你提供一个调度程序时,你想做的事情是做不到的。我没有注意到你在上使用调度程序是否有一个原因让您首先提供该计划程序(现在没有同步上下文)?我认为OP不希望在与先行任务相同的线程上安排继续,他希望它从创建该任务的线程执行。您能解释一下为什么要这样做吗?如果您有当前的同步上下文,此代码将在
t处死锁。Wait();
,因为等待不会处理已发布的任务。您能解释一下为什么要这样做吗?如果您有当前的同步上下文,此代码将在
t.Wait();
,因为等待不会处理已发布的任务。