how to manage an NDC-like log4net stack with async/await methods? (per-Task stack?)

前端 未结 1 1787
暗喜
暗喜 2021-01-04 03:42

In a normal/synchronous/single-threaded console app, NDC.Push works fine for managing the \'current item\' (potentially at multiple levels of nesting, but just 1 level for t

相关标签:
1条回答
  • 2021-01-04 04:31

    There isn't a good story for async logical call contexts right now.

    CallContext can't be used for this. The logical CallContext doesn't understand how async methods return early and resume later, so it will not always work correctly for code that uses simple parallelism such as Task.WhenAll.

    Update: CallContext was updated in .NET 4.5 RTW to correctly work with async methods.

    I looked into log4net; LogicalThreadContext is documented as using CallContext, but there was a bug that made it use the non-logical contexts (fixed in their SVN on Feb 2, 2012; the current 1.2.11 release does not include that fix). Even when it's fixed, though, it'll still not work with async (because the logical CallContext doesn't work with async).

    When I need an async logical call context, I make a class that contains the context data and keep all of my async methods in a functional style as instance members of that class. This is certainly not an ideal solution, but it's a dirty hack that works.

    In the meantime, please upvote the suggestion that Microsoft provide some mechanism for this.

    P.S. A concurrent dictionary keyed by Task won't work, because async methods are not necessarily running tasks (i.e., in your example code, at the using statement, Task.CurrentId would be null because there is no task actually executing at that point).

    And thread affinity has its own problems, too. You actually end up needing a separate thread for each independent asynchronous operation. Bye-bye, scalability...

    0 讨论(0)
提交回复
热议问题