了解 .Net 任务执行中的上下文

Understanding context in .Net Task execution

我一直在尝试理解 .Net 中任务执行中上下文的概念。但是,我仍然无法将 context 与 OS 线程的基本概念联系起来。在浏览 this blog 时,我对上下文是什么有了以下想法:

In GUI applications, there is a single GUI thread which has all the GUI elements. Now, because one needs to come in the GUI thread to access the GUI elements, I am assuming the GUI thread has the GUI elements initialized in its stack space which it doesn't share with other threads. Therefore, the awaitable needs to schedule the remainder of the function in the GUI thread if the remainder function wants to access some GUI element. Similarly, if we talk about HTTP application which accept HTTP get/post requests, there is a thread which gets spawned when a request arrives. This thread contains the request context like IP address of the user. Now, if the remainder function wants to access some HTTP context properties, it has to execute in that thread.

在阅读 this blog 时,我想到了 context being copied。这让我相信以下几点:

The context of a thread is data members like IP address, GUI elements etc. When the remainder of a function is scheduled after an awaitable completes, the remainder may need the context to be present, but not necessarily on the same thread. So, what is done is any thread is taken out of the thread pool and the context is copied onto that thread so that it is accessible. Thereafter, the remainder function is scheduled on this thread. This can cause a deadlock in the following way. Take GUI applications for example. At any time, there should be a unique thread having the GUI context. So, if the GUI thread blocks and doesn't release the context, the remainder function won't get scheduled.

任何人都可以为我澄清一下吗?上下文中到底是什么?上下文是如何传输的?以上我的理解哪个是对的,哪个是错的?


更新: 我读了 this blog,它有一行 And this extension method demonstrates how to invoke a function with a specified ExecutionContext (typically, captured from another thread)。这促使我相信我的第二个想法更接近正确。

每个上下文都不同。但一般来说,它们不会复制。上下文用于 安排 Tasks。即根据需要找到合适的线程其他资源,然后执行任务。

在某些上下文中(GUI),最重要的是线程。有一个 UI 线程,因此要求 GUI 上下文调度的任何 Task 必须安排 UI 线程执行那个 Task

在某些情况下(核心之前的ASP.Net),重要的是"ambient" request/response/session 对象。这些对象一次只能由一个线程访问,但可以使用 any 线程。因此上下文可以使用线程池线程,但需要确保它一次只执行一个 Task

并且在默认上下文中,没有特殊线程或任何其他特殊资源。与上面的 ASP.Net 上下文一样,任何线程池线程都可用于执行 Task,但它可以在线程池接受它们时尽可能快地安排 Tasks。