在与前一个相同的线程中继续执行任务

Lui*_*ipe 14 c# impersonation task-parallel-library

我有一个WebService,它创建一个任务和一个延续任务.

在第一个任务中我们设置Thread.CurrentPrincipal

因此,当ContinuationTask启动时,它不再具有Thread.CurrentPrincipal.

我想在ContinuationTask中指定它应该在与其前提相同的线程中运行.

我搜索过网络,但我只发现线程要在SynchronizationContext中运行,因此我开始认为我缺少一些基本规则,特别是关于Thread.Principal应该如何工作.

usr*_*usr 15

首先,不要TaskContinuationOptions.ExecuteSynchronously为此目的使用!您不能强制在同一个线程上继续.它只能以非常高的概率运行.总有一些情况它不起作用:太多的递归会导致TPL不能同步执行.海关TaskScheduler也没有义务支持这一点.

这是一种常见的误解,特别是因为它在网络上被错误地传播.以下是关于该主题的一些解读:http://blogs.msdn.com/b/pfxteam/archive/2012/02/07/10265067.aspx

如果您需要在同一个线程上运行,请执行以下操作:

Task.Factory.StartNew(() => { First(); Second(); });
Run Code Online (Sandbox Code Playgroud)

太简单.

让我通过展示替代解决方案来说明原因:

void MyCompositeTask()
{
  var result = First();
  Second(result);
}
Task.Factory.StartNew(() => MyCompositeTask());
Run Code Online (Sandbox Code Playgroud)

这看起来更直观:我们传递MyCompositeTask给TPL运行.TPL并不关心我们在回调中做了什么.我们可以做任何我们想做的事情,包括调用多个方法并传递结果.

  • @JesseCarter你不认为在另一个之后执行一个方法会保证主体持续存在吗?*普通方法调用之间的所有*都存在.深度递归在潜在的无限延续链中发生了很多.以下是ExecSync未生效的多种情况:http://blogs.msdn.com/b/pfxteam/archive/2012/02/07/10265067.aspx(可信来源). (2认同)

Jes*_*ter 5

来自我的 C# 教科书(C# 4.0 in a Nutshell):

您可以通过TaskContinuationOptions.ExecuteSynchronously在调用时指定来强制它们 [continuation tasks] 在同一个线程上执行 [作为它们的先行任务] ContinueWith:这可以通过减少间接性来提高非常细粒度的 continuation 的性能。

原则上我没有尝试过这个,但它似乎是你正在寻找的,并且可以与 Thread.CurrentPrincipal 结合使用。

这是指向MSDN 文章的链接,其中包含一些更具体的示例

  • 你不能强迫它。它只适用于非常高的概率!有 * 总是 * 情况下它不起作用。因为那个被否决了。 (3认同)

Gre*_*som 5

使用 TaskScheduler.FromCurrentSynchronizationContext() 调用延续:

Task UITask= task.ContinueWith(() =>
{
 this.TextBlock1.Text = "Complete"; 
}, TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

复制自/sf/answers/303190121/