如何防止任务继承父任务逻辑调用上下文



在使用Task时,我正尝试使用AsyncLocal作为线程本地存储的替代品。Run((和Async方法。我的问题是我需要下面的代码来打印

from t1 t1
from t1 t1
from t2 t2
from t2 t2

如果使用线程本地存储,这将是一种行为,但我得到的却是这种输出。

from t1 t1
from t1 t1
from t2 t1
from t2 t1

示例代码:

public class ClientClass {
public static void Main() 
{
AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
var t1 = Task.Run( async () => {
string a = _asyncLocalString.Value;
if (a == null) {
_asyncLocalString.Value = "t1";
}
a = _asyncLocalString.Value;
Console.WriteLine("from t1 " + a);
await Task.Delay(10);
string b = _asyncLocalString.Value;
Console.WriteLine("from t1 " + b);
var t2 = Task.Run( async () => {
string aa = _asyncLocalString.Value;
if (aa == null) {
_asyncLocalString.Value = "t2";
}
aa = _asyncLocalString.Value;
Console.WriteLine("from t2 " + aa);
await Task.Delay(10);
string bb = _asyncLocalString.Value;
Console.WriteLine("from t2 " + bb);
});
await t2;
});
t1.Wait();
}
} 

您可以在调用Task之前抑制流。后运行并恢复

public class ClientClass {
public static void Main() 
{
AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
var t1 = Task.Run(async () =>
{
string a = _asyncLocalString.Value;
if (a == null)
{
_asyncLocalString.Value = "t1";
}
a = _asyncLocalString.Value;
Console.WriteLine("from t1 " + a);
await Task.Delay(10);
string b = _asyncLocalString.Value;
Console.WriteLine("from t1 " + b);
ExecutionContext.SuppressFlow();
var t2 = Task.Run(async () =>
{
string aa = _asyncLocalString.Value;
if (aa == null)
{
_asyncLocalString.Value = "t2";
}
aa = _asyncLocalString.Value;
Console.WriteLine("from t2 " + aa);
await Task.Delay(10);
string bb = _asyncLocalString.Value;
Console.WriteLine("from t2 " + bb);
});
ExecutionContext.RestoreFlow();
await t2;
});
t1.Wait();
}
} 

提供

from t1 t1
from t1 t1
from t2 t2
from t2 t2

我所知道的唯一方法是使用ThreadPool。UnsafeQueueUserWorkItem:

public class ClientClass {
public static void Main() 
{
AsyncLocal<string> _asyncLocalString = new AsyncLocal<string>();
var t1 = Task.Run(async () =>
{
string a = _asyncLocalString.Value;
if (a == null)
{
_asyncLocalString.Value = "t1";
}
a = _asyncLocalString.Value;
Console.WriteLine("from t1 " + a);
await Task.Delay(10);
string b = _asyncLocalString.Value;
Console.WriteLine("from t1 " + b);
var tcs = new TaskCompletionSource<bool>();
ThreadPool.UnsafeQueueUserWorkItem(async s =>
{
string aa = _asyncLocalString.Value;
if (aa == null)
{
_asyncLocalString.Value = "t2";
}
aa = _asyncLocalString.Value;
Console.WriteLine("from t2 " + aa);
await Task.Delay(10);
string bb = _asyncLocalString.Value;
Console.WriteLine("from t2 " + bb);
((TaskCompletionSource<bool>)s).SetResult(true);
}, tcs);
await tcs.Task;
});
t1.Wait();
}
} 

相关内容

  • 没有找到相关文章

最新更新