gpt4 book ai didi

c# - 使用 PLINQ Extensions 时,线程标识是否被转移?

转载 作者:太空狗 更新时间:2023-10-29 18:16:43 26 4
gpt4 key购买 nike

我正在使用 .AsParallel().ForAll() 在 ASP.NET 请求的上下文中并行枚举一个集合。枚举方法依赖System.Threading.Thread.CurrentPrincipal。

我是否可以依靠用于将其 System.Threading.Thread.CurrentPrincipal 设置为处理 ASP.NET 请求的线程的 HttpContext.Current.User 的各个线程,还是我需要自己管理它?

问这个问题的另一种方式是 PLINQ 使用的线程是否继承了调用该操作的线程的标识?

最佳答案

不,身份不会自动传播到这些工作线程。事实上,如果您使用的组件是 HttpContext.User,您可以做的是在“主”线程中捕获当前“环境”HttpContext 实例并传播它到你的工作线程。这看起来像这样:

HttpContext currentHttpContext = HttpContext.Current;

myWorkItems.AsParallel().ForAll(wi =>
{
HttpContext.Current = currentHttpContext;

try
{
// anything called from here out will find/use the context of your original ASP.NET thread
}
finally
{
// Disassociate the context from the worker thread so that it is not held on to beyond its official lifetime
HttpContext.Current = null;
}
});

这是可行的,因为 HttpContext.Current 由静态线程支持,因此每个工作线程都将从您的主线程分配实例,并且从那时起对其所做的任何工作都将被视为当前实例。

现在,您必须意识到 HttpContext 及其相关类并非设计为线程安全的,因此这有点 hack。如果您只是从属性中读取,这并不是真正的问题。如果您没有使用依赖于 HttpContext.Current 的组件,那么不设置它会更“干净”,而是直接在工作程序中使用捕获的 currentHttpContext 变量。

最后,如果您真正需要的只是将当前主体传播到工作线程,那么您可以使用相同的方法来做到这一点:

Principal logicalPrincipal = Thread.CurrentPrincipal;

myWorkItems.AsParallel().ForAll(wi =>
{
Principal originalWorkerThreadPrincipal = Thread.CurrentPrincipal;
Thread.CurrentPrincipal = logicalPrincipal;

try
{
// anything called from here out will find the principal from your original thread
}
finally
{
// Revert to the original identity when work is complete
Thread.CurrentPrincipal = originalWorkerThreadPrincipal;
}
});

关于c# - 使用 PLINQ Extensions 时,线程标识是否被转移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8319439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com