ASP.NET 身份文化等待者代码

本文关键字:代码 等待 文化 NET 身份 ASP | 更新日期: 2023-09-27 18:36:58

在开发 ASP.NET MVC 应用程序的过程中,我遇到了CultureAwaiter,其实例在调用扩展方法WithCurrentCulture时返回。

我对Microsoft的异步模型比较陌生,所以我正在努力理解我在下面标记的代码中四行背后的直觉。请注意,我使用 ILSpy 从汇编文件版本"2.1.30612.0"中获取了这个......我认为 MS 还没有提供源代码供我们查看。

在这四行中,我假设在同一线程上同步运行,看起来变量currentCulture设置为当前线程的文化(到目前为止一切顺利)。但是,两行之后,它只是获取该变量并将当前线程的区域性设置为该变量(即只是反转赋值)。这有什么用?

另一方面,UI 区域性在这四行中的行为略有不同。请注意变量名称中"UI"/"Ui"的大小写。在这四行中的第二行,变量 currentUICulture 设置为当前线程的 UI 区域性(大概是为了"记住"它以供以后使用)。两行后,当前线程的 UI 区域性设置为不同的变量currentUiCulture(注意不同的大小写)...在方法开始时定义。

撇开我对异步模型的新手理解不谈,我至少期望 CurrentCulture 和 CurrentUICulture 在此方法中具有相同的获取/设置行为。我可能完全错了,但我的"直觉"告诉我,这四行中可能发生了不正确的分配。

谁能为我的理解提供一些说明?它可能与ILSpy有关吗?

// Microsoft.AspNet.Identity.TaskExtensions.CultureAwaiter<T>
public void UnsafeOnCompleted(Action continuation)
{
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture;
    this._task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(delegate
    {
        // WHAT'S GOING ON IN THE NEXT FOUR LINES?
        CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
        CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
        Thread.CurrentThread.CurrentCulture = currentCulture;
        Thread.CurrentThread.CurrentUICulture = currentUiCulture;
        try
        {
            continuation();
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = currentCulture;
            Thread.CurrentThread.CurrentUICulture = currentUICulture;
        }
    });
}

ASP.NET 身份文化等待者代码

这样做的目的是使用当前区域性设置运行延续,尽管它可能在不同的线程上运行。但我们不想以持久的方式修改该线程的区域性,因为我们不拥有该线程。它是共享的。因此,我们必须在退出之前恢复旧设置。

可能,反编译器只是显示误导性的变量名称。反射器正确执行:

public void UnsafeOnCompleted(Action continuation)
{
    CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
    CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture;
    this._task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(delegate {
        CultureInfo info1 = Thread.CurrentThread.CurrentCulture;
        CultureInfo currentUICulture = Thread.CurrentThread.CurrentUICulture;
        Thread.CurrentThread.CurrentCulture = currentCulture;
        Thread.CurrentThread.CurrentUICulture = currentUiCulture;
        try
        {
            continuation();
        }
        finally
        {
            Thread.CurrentThread.CurrentCulture = info1;
            Thread.CurrentThread.CurrentUICulture = currentUICulture;
        }
    });
}