Web API - 为每个线程设置 HttpRequestMessage id?

Web API - Set each thread with the HttpRequestMessage id?

我有一个用 c# 编码的网站 api。

Web api 使用与其他内部组件共享的功能。 它依赖于单线程流程并使用线程本地存储来存储对象和会话信息。 请不要说是好是坏,那是我必须面对的。

在网络中 api 我已经使用 SendAsync

实现了自定义消息处理程序 (DelagatingHandler)
protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)

它基于 TPL,有时会切换线程,当发生这种情况时,我基于线程的功能会变得混乱,因为我正在丢失线程上下文和分配给它的所有数据。

我的思路是唯一标识HttpRequestMessage, 我认为使用相关 ID 应该足够了

var requestId = request.GetCorrelationId();

但我想为任务中分配的每个线程存储 HttpRequestMessage 的相关 ID。

所以我的问题基本上是我是否可以识别在特定任务下分配的线程并为其分配 ID?

对于与上下文相关的问题,您可以使用 CallContext.LogicalSetData and CallContext.LogicalGetData,它只是在上下文之间流动的 IDictionary<string, object>,并且具有写时复制(浅拷贝)语义。

由于您的数据是不可变的(根据 docs),您可以将相关 ID 映射到线程管理的线程 ID:

protected async override Task<HttpResponseMessage> SendAsync(
                         HttpRequestMessage request, 
                         CancellationToken cancellationToken)
{
    var correlationId = request.GetCorrelationId();
    var threadId = Thread.CurrentThread.ManagedThreadId;

    CallContext.LogicalSetData(correlationId.ToString(), threadId);
}

稍后检索 if 以确保您在 "valid thread"。

可以找到关于 async-await 的通话上下文的好读物 here