首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#任务ConfigureAwait

C#任务ConfigureAwait
EN

Stack Overflow用户
提问于 2014-10-10 21:07:03
回答 2查看 2.6K关注 0票数 6

我以为我掌握了ConfigureAwait,然后我尝试了一个实验。

我的理解是,只有在存在同步上下文的情况下,ConfigureAwait(false)才会起作用。

ASP、WPF等应该有上下文,但控制台应用程序和服务应用程序不应该。

为了了解它是如何工作的,我制作了一个Web应用程序,并包括以下方法:

代码语言:javascript
复制
// GET api/values/5
public async Task<string> Get (int id)
{
    var syncCtx = SynchronizationContext.Current;

    int startThreadId = Thread.CurrentThread.ManagedThreadId;

    await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(true);

    int endThreadId = Thread.CurrentThread.ManagedThreadId;

    return "Start Thread ID: " + startThreadId.ToString() + 
            ": End Thread ID: " + endThreadId.ToString();
}

我的预测是,在没有将ConfigureAwaitConfigureAwait设置为true的情况下,我应该在等待之前和之后看到相同的线程ID。

我最初的几次测试正好证明了这一点,正如上面所示的那样。

以后的代码运行是在不同的线程ids上启动和结束的,而不考虑ConfigureAwait

我加入syncCtx是为了让自己相信我有自己的背景。

我读过的一个警告是,如果任务已经完成,您将不会得到相同的ID。这里是这样的吗?若然,为甚麽会出现这种情况?

我是否设置了一个天真或有缺陷的测试?如果是的话,什么才是适当的测试?

我在一个控制台/服务应用程序中开始使用这个路径,并意识到我没有得到相同的线程ID,我正在添加ConfigureAwait(false),这是我在大多数“最佳实践”编写ups时所推荐的。因为我喜欢看事情是如何工作的,所以我试着测试线程ID。看到它们的不同,我通过了大量的搜索,最终得到了上面的代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-10 21:22:48

执行ConfigureAwait(true) (或者只是放弃它,因为它是默认值)并不会使它在同一个线程上运行。它告诉SynchronizationContext.Current对其余的延续执行PostSend。未定义Post或Send如何实际运行该代码。

WindowsFormsSynchronizationContextDispatcherSynchronizationContext (WinForms和WPF的上下文)都将继续放置到消息泵( UI线程)要处理的消息队列中。

另一方面,AspNetSynchronizationContext (这是您正在运行的)只设置一些状态信息(比如将HttpContext.Current设置为其旧值),然后它在下一个可用线程池线程上对工作进行排队。ASP.NET没有“消息泵”,它只是在线程池上完成所有的工作,所以以后尝试从线程池中取出同一个线程是没有意义的,当继续发生时,该线程可能已经被破坏了。

您在获得幸运之前和之后看到相同ID的时间,以及在继续之前和之后同一个线程被从线程池中提取出来的时间。

我强烈建议您阅读MSDN杂志的文章"都是关于SynchronizationContext的",它详细解释了SynchronizationContext的工作原理,并详细介绍了.NET内置的4种上下文类型。

票数 8
EN

Stack Overflow用户

发布于 2014-10-10 21:22:43

SynchronizationContext != Thread。如果您在使用类似WPF的Dispatcher运行时,那么是的,它的SynchronizationContext恰好绑定到一个特定的线程上。然而,像ASP.NET和WCF这样的东西并不是线程仿射,它们只是带着特定的环境上下文,需要在接下来开始执行的任何线程上恢复它们。它们可能是特定线程池的仿射,但同样不是特定线程。

这正是引入SynchronizationContext抽象的原因:它允许不同的框架确切地决定关联对它们的意义,并允许异步/等待基础结构以完全不可知的方式在它们之上工作。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26308044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档