いいえ、IDはこれらのワーカースレッドに自動的に伝播されません。実際、使用しているコンポーネントが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
あります。したがって、これはちょっとしたハックです。プロパティから読み取るだけの場合、これは実際には問題ではありません。に依存するコンポーネントを使用していない場合は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;
}
});