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

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

问题描述

我是否正确地认为 async/await 本身与并发/并行无关,只不过是延续传递风格 (CPS) 实现?而真正的线程是由await传递/恢复的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?

如果这是正确的,我有以下关于 SynchronizationContext 的问题:
它保证将在同一线程上执行延续.

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

然而,是否有任何保证线程的上下文信息被持久化?我的意思是 NameCurrentPrincipalCurrentCultureCurrentUICulture 等等.它是否依赖于框架(ASP.NET、WinForms、WCF、WPF)?

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)?

推荐答案

我是否正确地认为 async/await 本身与并发/并行无关,只不过是 CPS 实现?

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

嗯,async/await是使用CPS的重写,所以你的核心理解是正确的.

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

关于并发"和并行",我会说它确实支持并发;您可以同时启动多个 async 操作,这些操作都在进行中".使用 Task.WhenAllTask.WhenAny 很容易做到这一点.

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.

此外,即使 async 本身并不意味着多线程",Task.Run 确实支持简单的 async 兼容多线程

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

而真正的线程是由等待传递/恢复的 SynchronizationContext 实例执行的?

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

这样想:CPS 重写创建的延续必须在某处运行.捕获的异步上下文"可用于安排延续.

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.

旁注:捕获的上下文实际上是 SynchronizationContext.Current 除非它为 null,在这种情况下捕获的上下文是 TaskScheduler.Current.

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

另一个重要的注意事项:上下文的捕获和恢复实际上取决于等待者"对象.因此,默认情况下,如果您 await 一个 Task(或任何其他内置的 awaitable),上下文将被捕获和恢复.但是如果你await ConfigureAwait(false) 的结果,那么上下文就不会被捕获.类似地,如果您await您自己的自定义等待,它不会捕获上下文(除非您对其进行编程).

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).

然而,是否有任何保证线程的上下文信息被持久化?我的意思是名称、CurrentPrincipal、CurrentCulture、CurrentUICulture 等

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

SynchronizationContextExecutionContext 不同.一个简单的答案是 ExecutionContext 总是流动",所以 CurrentPrincipal 流动(如果没有,它可能是一个安全问题,这就是为什么不flow ExecutionContext 总是以 Unsafe 结尾.

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).

在 UI 应用程序中,文化不会流动,但默认情况下,所有线程都一样.Name 绝对不会流动,除非你在同一个线程上恢复(例如,使用 UI SynchronizationContext).

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).

为了进一步阅读,我建议从我自己的 async 开始/await 教程,然后是 官方async/await FAQ.那就看看Stephen Toub关于ExecutionContext的博文 vs. 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.

您可能还会发现我的SynchronizationContext 文章很有帮助.

You may also find my SynchronizationContext article helpful.

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

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