![]() |
1
2
您希望做的是从根本上违背异步执行上下文的本质;您不需要(因此也不能保证)立即等待在异步上下文中创建的所有任务,等待的顺序与创建任务的顺序相同,或者根本不需要等待,但在调用上下文的范围内创建任务会使它们成为同一异步上下文周期的一部分。
将异步执行上下文视为不同于线程上下文可能很有挑战性,但异步性并不是并行性的同义词,而并行性正是逻辑线程所支持的。存储在线程本地存储中、不打算跨线程共享/复制的对象通常是可变的,因为逻辑线程内的执行始终能够保证相对受限的顺序逻辑(如果为了确保编译时优化不会给您带来麻烦,可能需要进行一些特殊处理,尽管这很少见,而且只在非常特定的场景中才有必要)。因此
无论如何,执行上下文,这不是一个独特的概念。NET(在其他平台上的实现可能在某些方面有所不同,尽管在我的经验中从来没有太多)非常类似于调用堆栈(并与之直接相关),但在某种程度上,它将新的异步任务视为堆栈上的新调用,这可能需要两者共享调用方在执行操作时的状态,以及分歧,因为调用方可能会继续创建更多任务,并以在读取连续指令集时不具有逻辑意义的方式创建/更新状态。通常建议在
除此之外,如前所述,为了确保所有嵌套上下文都能以可预测和安全的方式运行,通常建议只存储不可变的类型,并始终将上下文恢复到其以前的值(就像使用一次性堆栈机制所做的那样)。考虑写时复制行为最简单的方法是,好像每个新任务、新线程池工作项和新线程都有自己的上下文克隆,但如果它们指向相同的引用类型(即所有线程都有相同的
引用指针
)它们都有相同的实例;写时拷贝只是一种优化,可以在不必要时防止拷贝,但本质上可以完全忽略,并认为每个逻辑任务都有自己的拷贝
上下文的
(非常像这样
您的示例没有显示任何关于如何访问数据或传入数据的类型的内容
以实际的方式重申,例如,您存储
然而,不可变项的不可变集合永远不会污染另一个上下文,除非在执行上下文的流动方式方面存在根本性的错误(联系供应商、提交错误报告、发出警报等)
编辑:一些文章是写给那些想读一些比我在这里漫谈更连贯的东西的人的:) https://devblogs.microsoft.com/pfxteam/executioncontext-vs-synchronizationcontext/ https://weblogs.asp.net/dixin/understanding-c-sharp-async-await-3-runtime-context 为了进行一些比较,这里有一篇关于如何在JavaScript中管理上下文的文章,JavaScript是单线程的,但支持异步编程模型(我想这可能有助于说明它们之间的联系/区别): |
![]() |
2
1
逻辑调用上下文与执行上下文具有相同的流语义,因此
|
![]() |
Sante Kyaku · 为什么我要用等待来获得承诺的结果? 2 年前 |
![]() |
Tomas Kubes · 是最大并发数。NET任务有限吗? 2 年前 |
![]() |
punkish · 并行异步获取/等待承诺。全部的 2 年前 |
![]() |
dapidmini · 未捕获的承诺嵌套异步函数承诺错误处理 2 年前 |
![]() |
smith · 如何在vue中使用wait/async 2 年前 |