async 和 await 是单线程的真的吗?
async and await are single threaded Really?
我创建了以下代码:
using System;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
Console.WriteLine("M Start");
MyMethodAsync();
Console.WriteLine("M end");
Console.Read();
}
static async Task MyMethodAsync()
{
await Task.Yield();
Task<int> longRunningTask = LongRunningOperationAsync();
Console.WriteLine("M3");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
static async Task<int> LongRunningOperationAsync()
{
await Task.Delay(1000);
return 1;
}
}
}
输出:
M Start
M end
M3
1
很好,但是当我查看线程分析器时,它显示如下:
然后这个:
然后这个:
所以看起来我生成了线程,但是从 msdn 说:
From Asynchronous Programming with Async and Await : Threads
The async and await keywords don't cause additional threads to be
created. Async methods don't require multithreading because an async
method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the
method is active. You can use Task.Run to move CPU-bound work to a
background thread, but a background thread doesn't help with a process
that's just waiting for results to become available.
我是不是漏掉了或者不明白什么?
谢谢。
The async and await keywords don't cause additional threads to be created.
是的。它将 CPU 绑定或 I/O 绑定的工作从进程的线程池移动到其他线程,这样它就不会在 UI 线程或当前同步上下文中执行,它不会创建MSDN 描述中的新线程。
我在我的博客上解释 how async
and await
work with threads and contexts。综上所述,当await
需要等待一个异步操作完成时,它会"pause"当前的async
方法并且(默认)捕获一个"context".
异步操作完成后,"context"用于恢复async
方法。这个 "context" 是 SynchronizationContext.Current
,除非它是 null
,在这种情况下它是 TaskScheduler.Current
。在您的情况下,上下文最终成为线程池上下文,因此 async
方法的其余部分被发送到线程池。如果您 运行 来自 UI 线程的相同代码,上下文将是 UI 上下文,并且所有 async
方法将在 UI 线程上恢复.
我创建了以下代码:
using System;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
Console.WriteLine("M Start");
MyMethodAsync();
Console.WriteLine("M end");
Console.Read();
}
static async Task MyMethodAsync()
{
await Task.Yield();
Task<int> longRunningTask = LongRunningOperationAsync();
Console.WriteLine("M3");
//and now we call await on the task
int result = await longRunningTask;
//use the result
Console.WriteLine(result);
}
static async Task<int> LongRunningOperationAsync()
{
await Task.Delay(1000);
return 1;
}
}
}
输出:
M Start
M end
M3
1
很好,但是当我查看线程分析器时,它显示如下:
所以看起来我生成了线程,但是从 msdn 说:
From Asynchronous Programming with Async and Await : Threads
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.
我是不是漏掉了或者不明白什么? 谢谢。
The async and await keywords don't cause additional threads to be created.
是的。它将 CPU 绑定或 I/O 绑定的工作从进程的线程池移动到其他线程,这样它就不会在 UI 线程或当前同步上下文中执行,它不会创建MSDN 描述中的新线程。
我在我的博客上解释 how async
and await
work with threads and contexts。综上所述,当await
需要等待一个异步操作完成时,它会"pause"当前的async
方法并且(默认)捕获一个"context".
异步操作完成后,"context"用于恢复async
方法。这个 "context" 是 SynchronizationContext.Current
,除非它是 null
,在这种情况下它是 TaskScheduler.Current
。在您的情况下,上下文最终成为线程池上下文,因此 async
方法的其余部分被发送到线程池。如果您 运行 来自 UI 线程的相同代码,上下文将是 UI 上下文,并且所有 async
方法将在 UI 线程上恢复.