Ash*_*win 3 c# threadstatic async-await
每次等待完成"选项"时,是否正在使用ThreadStatic并设置上下文?还有另外一种方法吗?
public async void Test()
{
// This is in Thread 1
Foo foo = new Foo();
Context.context = "context1"; // This is ThreadStatic
string result = await foo.CallAsynx();
// This is most likely Thread 2
Context.context = "context1"; // This might be a different thread and so resetting context
}
Run Code Online (Sandbox Code Playgroud)
如果我不想使用ThreadStatic,现在有另一种方法吗?
Ste*_*ary 15
ThreadStatic
,ThreadLocal<T>
线程数据槽和CallContext.GetData
/或CallContext.SetData
不能正常工作async
,因为它们是特定于线程的.
最好的选择是:
this
); 或者你可以让你的lambdas捕获变量(在下面,编译器会隐式地将它作为参数通过this
).HttpContext.Items
(如果您使用的是ASP.NET 4.5).CallContext.LogicalGetData
/ CallContext.LogicalSetData
作为@Noseratio建议.您只能在逻辑线程上下文中存储不可变数据; 它只适用于.NET 4.5,并不适用于所有平台(例如,Win8).async
通过为该线程安装"主循环"(例如AsyncContext
来自我的AsyncEx库),强制所有延续回到同一个线程.Mar*_*kus 11
只是如果几年后有人有同样的问题并找到这个线程......
有一个新功能叫做
AsyncLocal<T>
Run Code Online (Sandbox Code Playgroud)
https://learn.microsoft.com/en-us/dotnet/api/system.threading.asynclocal-1?view=netcore-3.1
这适用于“async/await”,也适用于:
我只是用以下代码测试这三个:
private void StartTests() {
Thread.Sleep(1000);
Task.Run(() => DoWork1());
Task.Run(() => DoWork2());
}
private void DoWork1() {
ThreadContext.Context.Value = "Work 1";
Thread.Sleep(5);
Task.Run(() => PrintContext("1"));
Thread.Sleep(10);
Dispatcher.BeginInvoke(new Action(() => PrintContext("1")));
Thread.Sleep(15);
var t = new Thread(() => PrintContextT("1"));
t.Start();
}
private void DoWork2() {
ThreadContext.Context.Value = "Work 2";
Task.Run(() => PrintContext("2"));
Thread.Sleep(10);
Dispatcher.BeginInvoke(new Action(() => PrintContext("2")));
Thread.Sleep(10);
var t = new Thread(() => PrintContextT("2"));
t.Start();
}
private void PrintContext(string c) {
var context = ThreadContext.Context.Value;
Console.WriteLine("P: " + context + "-" + c);
Task.Run(() => PrintContext2(c));
}
private void PrintContext2(string c) {
Thread.Sleep(7);
var context = ThreadContext.Context.Value;
Console.WriteLine("P2: " + context + "-" + c);
}
private void PrintContextT(string c) {
var context = ThreadContext.Context.Value;
Console.WriteLine("T: " + context + "-" + c);
}
public class ThreadContext {
public static AsyncLocal<object> Context = new AsyncLocal<object>();
}
Run Code Online (Sandbox Code Playgroud)
输出:
P:工作2-2
P:工作1-1
P2:工作2-2
P:工作2-2
P2:工作1-1
P:工作1-1
P2:工作2-2
T:工作2-2
P2:工作1-1
T:工作1-1
归档时间: |
|
查看次数: |
5505 次 |
最近记录: |