首页 > 解决方案 > 了解 .Net 任务执行中的上下文

问题描述

我一直在尝试理解 .Net 中任务执行中上下文的概念。但是,我仍然无法理解context操作系统线程的基本概念。在浏览这个博客时,我对上下文是什么有了以下想法:

在 GUI 应用程序中,有一个包含所有 GUI 元素的 GUI 线程。现在,因为需要进入 GUI 线程来访问 GUI 元素,所以我假设 GUI 线程在其堆栈空间中初始化了 GUI 元素,它不与其他线程共享。因此,awaitable如果剩余函数想要访问某个 GUI 元素,则需要在 GUI 线程中调度函数的剩余部分。同样,如果我们谈论接受 HTTP get/post 请求的 HTTP 应用程序,那么当请求到达时就会产生一个线程。该线程包含请求上下文,例如用户的 IP 地址。现在,如果剩余函数想要访问一些 HTTP 上下文属性,它必须在那个线程中执行。

在阅读此博客时,我想到了context being copied. 这使我相信以下几点:

线程的上下文是数据成员,如 IP 地址、GUI 元素等。当函数的其余部分在可等待完成后调度时,其余部分可能需要上下文存在,但不一定在同一个线程上。因此,所做的是从线程池中取出任何线程,并将上下文复制到该线程上,以便可以访问它。此后,将在该线程上调度剩余函数。这可能会通过以下方式导致死锁。以 GUI 应用程序为例。在任何时候,都应该有一个具有 GUI 上下文的唯一线程。因此,如果 GUI 线程阻塞并且不释放上下文,则剩余函数将不会被调度。

谁能为我澄清一下?在上下文中究竟是什么?上下文是如何转移的?以上我的理解哪个是对的还是两个都是错的?


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

标签: c#asp.netasync-awaittasksynchronizationcontext

解决方案


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

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

在某些情况下(核心之前的 ASP.Net),重要的是“环境”请求/响应/会话对象。这些对象一次只能由一个线程访问,但可以使用任何线程。因此上下文可以使用线程池线程,但需要确保它一次只执行一个Task

在默认上下文中,没有特殊线程或任何其他特殊资源。就像上面的 ASP.Net 上下文一样,任何线程池线程都可以用来执行s,但它可以尽可能快地Task调度s,因为线程池会占用它们。Task


推荐阅读