使用C#中的新async/await关键字,现在会对使用ThreadStatic数据的方式(以及何时)产生影响,因为回调委托在与async启动的操作不同的线程上执行.例如,以下简单的控制台应用程序:
[ThreadStatic]
private static string Secret;
static void Main(string[] args)
{
Start().Wait();
Console.ReadKey();
}
private static async Task Start()
{
Secret = "moo moo";
Console.WriteLine("Started on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
await Sleepy();
Console.WriteLine("Finished on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Secret is [{0}]", Secret);
}
private static async Task Sleepy()
{
Console.WriteLine("Was on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
await Task.Delay(1000);
Console.WriteLine("Now on thread [{0}]", Thread.CurrentThread.ManagedThreadId);
}
Run Code Online (Sandbox Code Playgroud)
将输出以下内容:
Started on thread [9]
Secret is [moo moo]
Was on thread [9]
Now …Run Code Online (Sandbox Code Playgroud) 在普通/同步/单线程控制台应用程序中,NDC.Push可以很好地管理"当前项目"(可能在多个嵌套级别,但对于此示例仅为1级).
例如:
private static ILog s_logger = LogManager.GetLogger("Program");
static void Main(string[] args)
{
BasicConfigurator.Configure();
DoSomeWork("chunk 1");
DoSomeWork("chunk 2");
DoSomeWork("chunk 3");
}
static void DoSomeWork(string chunkName)
{
using (NDC.Push(chunkName))
{
s_logger.Info("Starting to do work");
Thread.Sleep(5000);
s_logger.Info("Finishing work");
}
}
Run Code Online (Sandbox Code Playgroud)
这将导致期望日志输出,显示"程序"右侧的"块X"NDC条目(基本配置器的默认模式)
232 [9] INFO程序块1 - 开始工作
5279 [9] INFO计划块1 - 完成工作
5279 [9] INFO程序块2 - 开始工作
10292 [9] INFO计划块2 - 完成工作
10292 [9] INFO程序块3 - 开始工作
15299 [9] INFO计划块3 - 完成工作
但是,我无法弄清楚如何使用"普通"异步方法来维护它.
例如,尝试这样做:
private static ILog s_logger = LogManager.GetLogger("Program");
static void Main(string[] …Run Code Online (Sandbox Code Playgroud)