在同一个线程中以前后续任务(Continuation Task in the same thread

2019-07-17 15:05发布

我有一个创建任务和后续任务的WebService的。

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

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

我想在ContinuationTask指定它应该在同一个线程作为其先行运行

我在网上搜索,但我只发现线程在运行的SynchronizationContext的要求,因此,我开始觉得我缺少一些基本的规则,特别是对于Thread.Principal应该如何工作。

Answer 1:

首先,不要使用TaskContinuationOptions.ExecuteSynchronously为了这个目的! 你不能强迫在同一线程上的延续。 它仅适用于非常高的概率。 总有一些地方不工作的情况:太多的递归调用将导致TPL不同步执行。 自定义TaskScheduler s的也没有义务来支持这一点。

这是一个普遍的误解,特别是因为它被错误地传播在网络上。 下面是有关该主题的一些阅读: http://blogs.msdn.com/b/pfxteam/archive/2012/02/07/10265067.aspx

如果你需要在同一线程上运行,这样做:

Task.Factory.StartNew(() => { First(); Second(); });

太简单。

让我说明为什么作品通过展示一种替代解决方案:

void MyCompositeTask()
{
  var result = First();
  Second(result);
}
Task.Factory.StartNew(() => MyCompositeTask());

这看起来更直观:我们通过MyCompositeTask到TPL运行。 该TPL不关心我们在回调做。 我们可以做任何我们想做的,包括调用多种方法和传递的结果。



Answer 2:

从我的C#教材(C#4.0中果壳):

你可以迫使他们[续任务]通过指定同一个线程[他们的前因]上执行TaskContinuationOptions.ExecuteSynchronously调用时ContinueWith :这可能与减轻间接非常细粒度的延续提高性能。

原则上我还没有试过,但它似乎是你在找什么,并可以与结合Thread.CurrentPrincipal中使用。

这里是一个链接MSDN文章有一些更具体的例子,以及



Answer 3:

设置池线程的身份是不是一个好主意。 它关系到你这个特定的线程,并与风险例外的情况下,“泄露”的身份,如果你忘了清除异常处理程序的身份。 您可以使用“泄漏”的身份运行不相关的任务结束了。

尝试通过WindowsIdentity对象的任务和使用假冒WindowsIdentity.Impersonate 。 这将允许你使用任何可用的线索,并安全地清除,即使发生异常的身份。

你可以尝试这样的事情:

WindowsPrincipal myPrincipal=...;
...
var identity=(WindowsIdentity)myPrincipal.Identity;
var task=Task.Factory.StartNew(ident=>{
        var id=(WindowsIdentity)ident;
        using(var context=id.Impersonate())
        {
            //Work using the impersonated identity here
        }
        return id;
    },identity).
.ContinueWith(r=>{
        var id = r.Result;
        using(var context=id.Impersonate())
        {
            //Work using the impersonated identity here
        }
});

using语句确保即使发生异常模拟的标识被清除。



Answer 4:

调用与TaskScheduler.FromCurrentSynchronizationContext()的延续:

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

从复制https://stackoverflow.com/a/4331287/503969



文章来源: Continuation Task in the same thread as previous