【问题标题】:Correlate calls across async boundaries?跨异步边界关联调用?
【发布时间】:2019-09-03 00:48:54
【问题描述】:

我需要关联监控工具的异步方法之间的调用(主要是每个高级请求的时间信息)。

例如 - 对于 Web 服务器请求,我想知道在 MethodA、MethodC 和 MethodH 中分别花费了多少时间,其中一些可能在它们之间的调用层次结构中。

如果不涉及异步方法(并假设是单线程应用程序),则具有请求生命周期的 ThreadLocal<T> 基本上可以工作,但鉴于异步调用可能会被任何线程调度,这不是一个选项。

在完整的框架上,我可以使用 HttpContext,但这在 .NET 核心中不可用。

除了将上下文参数传递给每个受监控的方法(无论是手动还是通过某种 AOP),还有哪些选项?

【问题讨论】:

  • HttpContext 仍然存在,但不再是全球性的。它仍然可以从任何控制器访问,或者注入IHttpContextAccessor

标签: multithreading .net-core async-await


【解决方案1】:

这似乎AsyncLocal 是最合适的解决方案。 AsyncLocal 是针对此类场景添加的 ExecutionContext 的抽象。对它的更新会影响跨异步边界的子异步调用以及从该方法恢复到父级的任何部分,但不会影响在更新之前开始且仍在进行中的任何异步调用。

这在OpenTracing 中用于这个确切的用例。您在进入请求处理程序时设置 AsyncLocal,然后在退出时将其清除:

class Example
{
    static AsyncLocal<string> requestId = new AsyncLocal<string>();

    static async Task Handler()
    {
        requestId.Value = GetRequestId();
        await DoWork();
        requestId.Value = null;
     }
}

【讨论】:

    猜你喜欢
    • 2014-05-29
    • 2021-04-16
    • 2012-03-04
    • 2011-07-03
    • 1970-01-01
    • 2012-06-02
    • 2018-12-24
    • 2011-08-31
    相关资源
    最近更新 更多