Joe*_*ger 8 c# asp.net multithreading plinq
我正在使用.AsParallel().ForAll()在ASP.NET请求的上下文中并行枚举一个集合.枚举方法依赖于System.Threading.Thread.CurrentPrincipal.
我可以依赖于用于将System.Threading.Thread.CurrentPrincipal设置为处理ASP.NET请求的线程的HttpContext.Current.User的单个线程,还是我需要自己管理?
问这个问题的另一种方法是PLINQ使用的线程是否继承了调用该操作的线程的标识?
Dre*_*rsh 11
不,身份不会自动传播到这些工作线程.实际上,如果您正在使用的组件是HttpContext.User您可以捕获HttpContext"main"线程中的当前"环境" 实例并将其传播到工作线程.这看起来像这样:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为它HttpContext.Current是由线程静态支持的,因此每个工作线程都将从主线程中分配实例,并且从该点开始对其执行的任何工作都会将其视为当前实例.
现在,你必须要知道HttpContext它的相关类并不是设计为线程安全的,所以这有点像黑客.如果你只是从房产中读取这不是一个真正的问题.如果你没有使用依赖的组件,HttpContext.Current那么不设置它就会"更干净",而只是currentHttpContext直接在worker中使用捕获的变量.
最后,如果您真正需要的是将当前主体传播到工作线程,那么您可以使用相同的方法来实现:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2686 次 |
| 最近记录: |