C# 理解.Net任务执行中的上下文
我一直在试图理解.Net中任务执行中上下文的概念。然而,我仍然无法将C# 理解.Net任务执行中的上下文,c#,asp.net,async-await,task,synchronizationcontext,C#,Asp.net,Async Await,Task,Synchronizationcontext,我一直在试图理解.Net中任务执行中上下文的概念。然而,我仍然无法将上下文与操作系统线程的基本概念联系起来。在经历的过程中,我大致了解了什么是上下文: 在GUI应用程序中,只有一个GUI线程具有所有 GUI元素。现在,因为需要进入GUI线程 访问GUI元素,我假设GUI线程拥有GUI 元素在其堆栈空间中初始化,但不与之共享 其他线程。因此,可等待的需要安排 如果余数函数 想要访问一些GUI元素。类似地,如果我们谈论HTTP 接受HTTP get/post请求的应用程序,有一个线程 当请求到达时生
上下文
与操作系统线程的基本概念联系起来。在经历的过程中,我大致了解了什么是上下文:
在GUI应用程序中,只有一个GUI线程具有所有
GUI元素。现在,因为需要进入GUI线程
访问GUI元素,我假设GUI线程拥有GUI
元素在其堆栈空间中初始化,但不与之共享
其他线程。因此,可等待的
需要安排
如果余数函数
想要访问一些GUI元素。类似地,如果我们谈论HTTP
接受HTTP get/post请求的应用程序,有一个线程
当请求到达时生成。此线程包含请求上下文,如用户的IP地址。现在,如果剩下的
函数要访问一些HTTP上下文属性,它必须在该线程中执行
在阅读时,我突然想到要复制上下文。这使我相信:
线程的上下文是数据成员,如IP地址、GUI元素
等。当函数的剩余部分在等待的
完成后,其余部分可能需要上下文,但不需要
必须在同一条线上。所以,所做的是任何线程都是
从线程池中取出,并将上下文复制到该线程池中
线程,以便可以访问。此后,将使用余数函数
已在此线程上计划。这可能会以以下方式导致死锁。以桂为例
例如,应用程序。在任何时候,都应该有一个唯一的线程
具有GUI上下文。因此,如果GUI线程阻塞并且没有
释放上下文,剩余函数将不会被调度
谁能帮我澄清一下吗?上下文中到底是什么?语境是如何传递的?我的上述理解中哪一个是对的,或者两者都是错的
更新:
我读了,它有一行,这个扩展方法演示了如何使用指定的ExecutionContext调用函数(通常是从另一个线程捕获的)
。这促使我相信我的第二个想法更接近于正确性。每个上下文都是不同的。但总的来说,它们不是复制品。上下文用于计划任务
。也就是说,根据需要找到合适的线程和其他资源,然后执行任务
在某些上下文(GUI)中,最重要的是线程。有一个UI线程,因此要求GUI上下文调度的任何任务
都必须安排UI线程执行该任务
在某些上下文中(ASP.Net在core之前),重要的是“环境”请求/响应/会话对象。这些对象一次只能由一个线程访问,但可以使用任何线程。因此,上下文可以使用线程池线程,但需要确保它一次只执行一个任务
在默认上下文中,没有特殊线程或任何其他特殊资源。与上面的ASP.Net上下文一样,任何线程池线程都可以用来执行任务
,但它可以在线程池执行任务
时尽快安排这些任务。您能否更具体地说明您有什么问题?他们说的是同一件事,但方式略有不同。两者之间存在着微妙的差异。第一个描述指出,应该始终在特定线程(具有上下文)上调度剩余函数。第二种描述是,上下文就像一个数据结构,可以复制到任何线程上,然后余数函数可以在该线程中执行。我的问题是这些描述是否正确?
与实际发生的情况非常接近。确保这些描述是正确的。当谈论任务和延续时,你可以看看。如果您从Task.Run
开始,最终将进入一个执行此SynchronizationContext实例的方法。中讨论的有关ConfigureAwait()方法的信息可能会进一步有助于澄清与上下文相关的问题。我读了更多的内容,我认为您的答案现在对我有意义。如果我们暂时忘记了SynchronizationContext
是ExecutionContext
的一部分,那么我说的上下文就像需要的特定线程一样,或者只有一个线程能够访问环境对象,实际上是SynchronizationContext
。然而,我在一个函数中创建的所有临时变量都需要传递给剩余函数,因为它可能被安排在其他线程上,它们构成了ExecutionContext
的一部分。