溫故知新,CSharp遇見AsyncLocal,在ASP.Net Core 6.0和2.1中HttpContextAccessor前後設計變化

image

HttpContextAccessor In ASP.Net Core 2.1

https://github.com/dotnet/aspnetcore/blob/v2.1.33/src/Http/Http/src/HttpContextAccessor.cs

public class HttpContextAccessor : IHttpContextAccessor
{
    private static AsyncLocal<HttpContext> _httpContextCurrent = new AsyncLocal<HttpContext>();

    public HttpContext HttpContext
    {
        get
        {
            return _httpContextCurrent.Value;
        }
        set
        {
            _httpContextCurrent.Value = value;
        }
    }
}

HttpContextAccessor In ASP.Net Core 6.0

https://github.com/dotnet/aspnetcore/blob/v6.0.4/src/Http/Http/src/HttpContextAccessor.cs

/// <summary>
/// Provides an implementation of <see cref="IHttpContextAccessor" /> based on the current execution context.
/// </summary>
public class HttpContextAccessor : IHttpContextAccessor
{
    private static readonly AsyncLocal<HttpContextHolder> _httpContextCurrent = new AsyncLocal<HttpContextHolder>();

    /// <inheritdoc/>
    public HttpContext? HttpContext
    {
        get
        {
            return  _httpContextCurrent.Value?.Context;
        }
        set
        {
            var holder = _httpContextCurrent.Value;
            if (holder != null)
            {
                // Clear current HttpContext trapped in the AsyncLocals, as its done.
                holder.Context = null;
            }

            if (value != null)
            {
                // Use an object indirection to hold the HttpContext in the AsyncLocal,
                // so it can be cleared in all ExecutionContexts when its cleared.
                _httpContextCurrent.Value = new HttpContextHolder { Context = value };
            }
        }
    }

    private class HttpContextHolder
    {
        public HttpContext? Context;
    }
}

解決AsyncLocal在await環境中會發生複製,導致不能及時清除歷史的HttpContext的問題。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章