dev*_*hog 40 c# multithreading task-parallel-library async-await c#-5.0
我是TPL的新手,我想知道:C#5.0中新增的异步编程支持(通过new async
和await
关键字)如何与线程的创建有关?
具体来说,async/await
每次使用它们时是否使用创建新线程?如果有许多嵌套方法使用async/await
,是否为每个方法创建了一个新线程?
Adr*_*der 45
总之NO
async和await关键字不会导致创建其他线程.异步方法不需要多线程,因为异步方法不能在自己的线程上运行.该方法在当前同步上下文上运行,并仅在方法处于活动状态时在线程上使用时间.您可以使用Task.Run将CPU绑定的工作移动到后台线程,但后台线程无助于正在等待结果可用的进程.
Elo*_*Elo 16
根据 MSDN :async 关键字
异步方法同步运行,直到它到达它的第一个 await 表达式,此时该方法将挂起,直到等待的任务完成。同时,控制权返回给方法的调用者,如下一节中的示例所示。
这是检查它的示例代码:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
private void Print(string txt)
{
string dateStr = DateTime.Now.ToString("HH:mm:ss.fff");
Console.WriteLine($"{dateStr} Thread #{Thread.CurrentThread.ManagedThreadId}\t{txt}");
}
private void Run()
{
Print("Program Start");
Experiment().Wait();
Print("Program End. Press any key to quit");
Console.Read();
}
private async Task Experiment()
{
Print("Experiment code is synchronous before await");
await Task.Delay(500);
Print("Experiment code is asynchronous after first await");
}
}
Run Code Online (Sandbox Code Playgroud)
我们在另一个 Thread 上执行 await 后看到 Experiment() 方法的代码。
但是如果我用我自己的代码(方法SomethingElse)替换Task.Delay:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.Run();
}
private void Print(string txt)
{
string dateStr = DateTime.Now.ToString("HH:mm:ss.fff");
Console.WriteLine($"{dateStr} Thread #{Thread.CurrentThread.ManagedThreadId}\t{txt}");
}
private void Run()
{
Print("Program Start");
Experiment().Wait();
Print("Program End. Press any key to quit");
Console.Read();
}
private async Task Experiment()
{
Print("Experiment code is synchronous before await");
await SomethingElse();
Print("Experiment code is asynchronous after first await");
}
private Task SomethingElse()
{
Print("Experiment code is asynchronous after first await");
Thread.Sleep(500);
return (Task.CompletedTask);
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到线程保持不变!
总之,我会说 async/await 代码可以使用另一个线程,但前提是该线程是由另一个代码创建的,而不是由 async/await 创建的。
在这种情况下,我认为Task.Delay
创建了线程,所以我可以得出结论 async/await 不会像@Adriaan Stander 所说的那样创建新线程。
很抱歉在聚会上迟到了。
我是 TPL 的新手,我想知道:C# 5.0 的新异步编程支持(通过新的 async 和 await 关键字)与线程的创建有何关系?
async/await
不是为了创建线程而引入的,而是为了最佳地利用当前线程。
您的应用程序可能会读取文件、等待来自另一台服务器的响应,甚至执行具有高内存访问权限的计算(任何 IO 任务)。这些任务不是 CPU 密集型的(任何不会使用 100% 线程的任务)。
考虑一下您正在处理 1000 个非 CPU 密集型任务的情况。在这种情况下,创建 1000 个操作系统级线程的过程可能比在单个线程上执行实际工作消耗更多的 CPU 和内存(Windows 中每个线程 4mb,4MB * 1000 = 4GB)。同时,如果您按顺序运行所有任务,则可能必须等到 IO 任务完成。这最终会在很长的时间内完成任务,同时保持 CPU 空闲。
由于我们需要并行性来快速完成多个任务,同时所有并行任务都不会占用 CPU,但创建线程效率低下。
编译器将在对方法的任何方法调用async
(通过 await调用)时中断执行,并立即执行当前代码分支之外的代码,一旦await
到达,执行将进入前一个async
. 这将一次又一次地重复,直到所有异步调用完成并awaiters
得到满足。
如果任何异步方法在没有调用异步方法的情况下具有沉重的 CPU 负载,那么是的,您的系统将变得无响应,并且在当前任务完成之前不会调用所有剩余的异步方法。
归档时间: |
|
查看次数: |
22260 次 |
最近记录: |