异步/等待:ConfigureAwait的异常行为 [英] Async/Await: Unexpected behaviour of ConfigureAwait

查看:77
本文介绍了异步/等待:ConfigureAwait的异常行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在ASP.NET MVC中执行以下代码,则即使在ManagedThreadId更改的情况下,您也可以在调试窗口"中看到在await之后它将正确还原线程的区域性:

If you execute the following code in ASP.NET MVC, you can see in Debugging Window that it will correctly restore the thread's culture after await, even if ManagedThreadId changes:

public async Task<ActionResult> Index()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture);

    await SomeMethod();

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture);

    return View();
}

private async Task SomeMethod()
{
    await Task.Delay(100).ConfigureAwait(false);
}

然后我只是将ConfigureAwait(false)从SomeMethod()移到Index(),除此之外,它与上面的代码相同:

Then I just move ConfigureAwait(false) from SomeMethod() to Index(), except for this, it's the same code as above:

public async Task<ActionResult> Index()
{
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-DE");

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture);

    await SomeMethod().ConfigureAwait(false);

    Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
    Debug.WriteLine(Thread.CurrentThread.CurrentUICulture);

    return View();
}

private async Task SomeMethod()
{
    await Task.Delay(100);
}

现在它不能恢复我的文化,但始终将其设置为new CultureInfo("en-US").但是我希望使用这两种方法,结果必须相同.绝对不清楚,为什么会发生.

Now it doesn't restore my culture but always set it to new CultureInfo("en-US"). But I expect that using both methods, the result must be the same. It's absolutely unclear, why it's happening.

推荐答案

如果使用await task.ConfigureAwait(false),则该方法的其余部分(以及从那里调用的任何内容)将不会在原始上下文中执行.但这不会影响逻辑调用树中更高的任何代码.

If you use await task.ConfigureAwait(false), then the rest of that method (and whatever you call from there) will not execute on the original context. But this won't affect any code higher up in the logical call tree.

我认为这是唯一可行的方法.如果更高的代码必须在原始上下文上执行(这是很常见的),那么ConfigureAwait()在库代码内部的某个地方确实不会影响它.

And I think this is the only logical way to do it. If the code higher up has to be executed on the original context (which is quite common), then ConfigureAwait() somewhere deep inside library code really shouldn't affect it.

更具体地讲,如果ConfigureAwait()根据您的表现,以下在Winforms中使用await的简单示例将不起作用:

To make this more concrete, the following simple example of using await in Winforms wouldn't work if ConfigureAwait() behaved according to you:

async void ButtonClicked(object sender, EventArgs e)
{
    textBlock.Text = "Downloading";
    await DownloadAsync();
    textBlock.Text = "Finished";
}

async Task DownloadAsync()
{
    data = await new HttpClient().GetStringAsync(url).ConfigureAwait(false);
}

这篇关于异步/等待:ConfigureAwait的异常行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆