2016-11-29 54 views
1

我有一个多线程应用程序与异步处理(它本身使用很多线程)。如果没有异步操作,那么很容易记录并追踪执行流程,因为只需将当前线程标识符放到日志中即可看到哪个日志行由哪个线程执行。登录多线程异步代码

如何在异步环境中实现类似的事情?通常当await被调用时,下面的代码被分配给另一个线程(并且我确信,我相信线程池管理器可以有效地为我执行这些分配)。问题是,突然间我没有这个固定的执行流程的线程ID,很难将这两个部分放在一起。

在整个代码中是否有任何可以保留的任务标识符?我的意思是让我们说在方法中有5个等待电话。使用线程ID,我可以在日志中看到多达6个不同的ID。我想要一件事,而且我更喜欢它是否已经存在(我知道我可以创建一个对象并将它传递给我的日志功能,但是如果已经存在,它会更好)。

是Task.Id还是Task.CurrentId适合这个目的,还是别的什么?

+0

您可以简单地为要创建的每个任务生成标识(例如,使用自动增量)。通过它(例如'ContinueWith')是另一个问题。 – Sinatr

+0

我更问是否有可以使用的标识符。我知道它可以手动编程,但这实际上是我想避免的。 – Wapac

+0

Task.Id是Task实例的标识符,但是如果您阅读本文,您将获得更多有关它的信息:[Task.Id上的几个字](http://blog.stephencleary.com/2013/03 /a-few-words-on-taskid-and.html) – Fabio

回答

3

你指的是“相关性ID”,或者是什么log4net调用“嵌套诊断上下文”(NDC)。无论您拥有哪种日志框架,都应该有一个,最有可能的一个已经与async一起工作。

如果您需要建立自己的,我建议你把一个ID(或ID的不变堆栈)为AsyncLocal<T>(基本上是LogicalSetData但有一个更易于使用和更便携API) 。请注意,异步上下文数据应该是不可变的。有关更多信息,请参见my blog

0

我认为答案为“是[有]一个蓄势待发,可用于标识”可能是否定的,但你可以使用CallContext,特别LogicalSetData只是SetData(),并为实例添加一个GUID这将流过所有异步等待叉。