gpt4 book ai didi

c# - TPL 任务的 ThreadStatic

转载 作者:可可西里 更新时间:2023-11-01 07:58:16 27 4
gpt4 key购买 nike

怎么会像ThreadStatic在 TPL 任务中使用?我的理解(“Wrox Professional Parallel Programming with C#”,第 74 页)是任务可以在执行期间从一个线程切换到另一个线程。

我想做什么?

我想在静态类中维护一个 session ID,这样我就不需要将此 ID 传递给我的所有方法。我的库中有 login(id)logout(id) 等方法,还有许多操作与此 id 关联的凭据的方法。但我不想将此 id 传递给每个方法。我可以确保在不同 session 的不同线程中调用我的库。因此,将 login() 中的 id 保存在 ThreadStatic 变量中将起作用。

现在我想使用由 ThreadPool 为我创建的 TPL 任务。我可以将我的 session ID 传递给任务,但如果我将此 ID 存储在 ThreadStatic 变量中,那么如果我的任务切换线程,它将无法生存。

最佳答案

TPL 和 .Net 4.5 的异步流 ExecutionContext ,这意味着您可以使用 CallContext.LogicalSetData(string, object)CallContext.GetLogicalData(string)与使用 ThreadStatic 的方式大致相同.但是,它确实会导致显着的性能损失。这已在 .Net 4.6 及更高版本(包括 .Net Standard 1.3 及更高版本)中公开 the AsyncLocal<> wrapper .

参见 Async Causality Chain Tracking , How to include own data in ExecutionContext , 和 ExecutionContext vs SynchronizationContext进行更深入的研究。

使用示例:

class Program
{
static async void Main(string[] args)
{
Logger.Current = new Logger("Test Printer");

Logger.Current.Print("hello from main");
await Task.Run(() => Logger.Current.Print($"hello from thread {Thread.CurrentThread.ManagedThreadId}"));
await Task.Run(() => Logger.Current.Print($"hello from thread {Thread.CurrentThread.ManagedThreadId}"));
}
}

class Logger
{
private string LogName;

public Logger(string logName)
{
if (logName == null)
throw new InvalidOperationException();

this.LogName = logName;
}

public void Print(string text)
{
Console.WriteLine(LogName + ": " + text);
}

private static AsyncLocal<Logger> _logger = new AsyncLocal<Logger>();
public static Logger Current
{
get => _logger.Value;
set => _logger.Value = value;
}
}
}

打印:

Test Printer: hello from main  Test Printer: hello from thread 11 Test Printer: hello from thread 10

关于c# - TPL 任务的 ThreadStatic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6896652/

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