在C#中理解上下文5异步/的await [英] Understanding context in C# 5 async/await

查看:219
本文介绍了在C#中理解上下文5异步/的await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是纠正异步/的await本身无关并发/并行性和无非就是延续传递风格(CPS)的实施吗?而真正的线程是由的SynchronizationContext 进行实例等待通/恢复?

如果这是正确的我对的SynchronizationContext 以下问题:结果
它保证继续将在同一线程上执行。

不过,是否有线程的上下文信息被永久保存的任何担保?我的意思是名称 CurrentPrincipal 的CurrentCulture 的CurrentUICulture 等是否依赖于框架(ASP.NET,WinForms的,WCF,WPF)?


解决方案

  

我是正确的异步/的await本身无关并发/并行性和无非就是CPS实现的更多?


好吧,异步 / 等待是使用CPS,让你的核心理解是正确的重写。

关于并发和并行,我会说,它确实使并发性;你可以在同一时间启动多个异步操作,这些操作都是飞行中。这是很容易与 Task.WhenAll Task.WhenAny

此外,尽管异步本身并不意味着多线程 Task.Run 并能够轻松异步兼容多线程


  

和真正的线程是由等待通行证/恢复的SynchronizationContext实例执行?


认为它是这样的:由CPS重写创建的延续有某处运行的 的。捕获的异步上下文,可以用来计划的延续。

附注:捕捉的背景居然是 SynchronizationContext.Current ,除非它是空的,在这种情况下,拍摄的背景是 TaskScheduler.Current

另一个重要的注意事项:捕捉和上下文的恢复实际上是上升到awaiter对象。因此,在默认情况下,如果伺机 A 工作(或任何其他内置awaitable),上下文会捕获并恢复。但是,如果你等待的结果ConfigureAwait(假),那么上下文不会捕获。同样,如果您等待自己的自定义awaitable,也不会捕捉范围内(除非你把它编程为)。


  

不过,是否有线程的上下文信息被永久保存的任何担保?我的意思是名称,CurrentPrincipal,的CurrentCulture,的CurrentUICulture,等等。


的SynchronizationContext 的ExecutionContext 不同。简化的答案是,的ExecutionContext 总是流动,所以 CurrentPrincipal 流(如果它没有,它可能是一个安全问题,这就是为什么不流动的API 的ExecutionContext 总是不安全)。

结束

在UI应用,文化不流动,但默认情况下它的所有线程在同一反正。 名称是绝对不会流出,除非你继续在同一个线程(例如,使用一个UI 的SynchronizationContext )。


有关一些进一步的阅读,我建议先从我自己的 异步 / 的await 教程,然后的官方异步 / 等待常见问题 。然后看看<一个href=\"http://blogs.msdn.com/b/pfxteam/archive/2012/06/15/executioncontext-vs-synchronizationcontext.aspx\">Stephen Toub的博客文章对的ExecutionContext 的SynchronizationContext

您也可以找到我的 的SynchronizationContext 文章帮助。

Am I correct that async/await itself has nothing to do with concurrency/parallelism and is nothing more than continuation-passing style (CPS) implementation? And the real threading is performed by SynchronizationContext instance that await passes/restores?

If that is correct I have the following question about SynchronizationContext:
it guarantees that a continuation will be executed on the same thread.

However, are there any guaranties that the thread's context information is persisted? I mean Name, CurrentPrincipal, CurrentCulture, CurrentUICulture, etc. Does it depend on framework (ASP.NET, WinForms, WCF, WPF)?

解决方案

Am i correct that async/await itself has nothing to do with concurrency/parallelism and is nothing more than CPS implementation?

Well, async / await is a rewriting that uses CPS, so your core understanding is correct.

Regarding "concurrency" and "parallelism", I would say that it does enable concurrency; you can start multiple async operations which are all "in flight" at the same time. This is easy to do with Task.WhenAll and Task.WhenAny.

Also, even though async by itself doesn't imply "multithreading", Task.Run does enable easy async-compatible multithreading

And the real threading is performed by SynchronizationContext instance that await passes/restores?

Think of it this way: the continuation created by the CPS rewriting has to run somewhere. The captured "async context" can be used to schedule the continuation.

Side note: the captured context is actually SynchronizationContext.Current unless it is null, in which case the captured context is TaskScheduler.Current.

Another important note: the capturing and restoring of the context is actually up to the "awaiter" object. So, by default, if you await a Task (or any other built-in awaitable), the context will be captured and restored. But if you await the result of ConfigureAwait(false), then the context is not captured. Similarly, if you await your own custom awaitable, it won't capture the context (unless you program it to).

However, are there any guaranties that the thread's context information is persisted? I mean Name, CurrentPrincipal, CurrentCulture, CurrentUICulture, etc.

SynchronizationContext is different than ExecutionContext. A simplified answer is that ExecutionContext always "flows", so CurrentPrincipal flows (if it didn't, it could be a security issue, which is why APIs that don't flow ExecutionContext always end in Unsafe).

In UI apps, culture doesn't flow, but by default it's the same for all threads anyway. Name is definitely not going to flow, unless you resume on the same thread (e.g., using a UI SynchronizationContext).


For some further reading, I recommend starting with my own async / await tutorial and then the official async / await FAQ. Then take a look at Stephen Toub's blog post on ExecutionContext vs. SynchronizationContext.

You may also find my SynchronizationContext article helpful.

这篇关于在C#中理解上下文5异步/的await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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