我是TPL的新手,我想知道:C#5.0新增的异步编程支持(通过新的异步和等待关键字)与线程的创建有什么关系?
具体来说,每次使用异步/等待是否都会创建一个新线程?如果有许多嵌套方法使用异步/等待,那么是否为这些方法中的每一个都创建了一个新线程?
抱歉来晚了。
我是TPL的新手,我想知道:对C#5.0来说是新的异步编程支持(通过新的异步和等待关键字)与线程的创建有何关系?
异步/等待不是为创建线程而引入的,而是为了最佳地利用当前线程。
你的应用程序可能会读取文件,等待另一台服务器的响应,甚至使用高内存访问进行计算(只需执行任何IO任务)。这些任务不是CPU密集型的(任何不会100%使用线程的任务)。
考虑一下处理1000个非CPU密集型任务的情况。在这种情况下,创建1000个OS级线程的过程可能会比在单个线程上实际工作消耗更多的CPU和内存(Windows中每个线程4mb,4mb*1000=4GB)。同时,如果按顺序运行所有任务,则可能需要等待IO任务完成。最终需要很长时间才能完成任务,同时保持CPU空闲。
由于我们需要并行性来快速完成多个任务,同时所有并行任务都不需要CPU,但创建线程效率很低。
编译器将在对async
方法的任何方法调用时中断执行(使用wait调用)并立即在当前代码分支之外执行代码,一旦到达wait
,执行将进入之前的async
。这将一次又一次地重复,直到所有异步调用都完成并且满足它们的等待者
。
如果任何异步方法在没有调用异步方法的情况下具有较重的CPU负载,那么是的,您的系统将变得无响应,并且在当前任务完成之前不会调用所有剩余的异步方法。
根据MSDN:async关键字
异步方法同步运行,直到到达其第一个等待表达式,此时该方法将挂起,直到等待的任务完成。同时,控件返回给方法的调用方,如下一节中的示例所示。
下面是检查它的示例代码:
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");
}
}
在另一个线程上执行wait之后,我们看到了experience()方法的代码。
但如果我更换任务。由我自己的代码延迟(方法SomethingElse):
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);
}
}
我注意到线程保持不变!
总之,我要说异步/等待代码可以使用另一个线程,但前提是该线程是由另一个代码创建的,而不是由异步/等待创建的。
在这种情况下,我认为任务。延迟
创建了线程,所以我可以得出结论async/wait不会像@Adriaan Stander所说的那样创建一个新线程。
总之没有
使用异步和等待的异步编程:线程
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。 Async function 让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示: async function f() { return 1; } 在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被
在第一章节,我们简要介绍了async/.await,并用它来构建一个简单的服务器。本章将更为详细讨论async/.await的它如何工作以及如何async代码与传统的 Rust 程序不同。 async/.await是 Rust 语法的特殊部分,它使得可以 yield 对当前线程的控制而不是阻塞,从而允许在等待操作完成时,其他代码可以运行。 async有两种主要的使用方式:async fn和asyn
用asyncio提供的@asyncio.coroutine可以把一个generator标记为coroutine类型,然后在coroutine内部用yield from调用另一个coroutine实现异步操作。 为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。 请注意,async和await是针对coroutin
它与这个问题有着松散的联系:std::thread是否在C11中合并?。虽然问题不同,但意图是一样的: 问题1:使用自己的(或第三方库)线程池来避免昂贵的线程创建是否仍然有意义? 另一个问题的结论是,您不能依赖进行池化(可能是,也可能不是)。然而,std::async(launch::async)似乎有更高的机会被合并。 它不认为这是标准强制的,但我认为,如果线程创建缓慢,所有好的C 11实现都会
想象一下一个按下按钮就能被喜欢的帖子。这个按钮修改了一个远程数据库,所以需要一点时间来将like与特定的帖子相关联。 不喜欢 做了<-------不喜欢做 做完<--------喜欢做完
我有一个安装了ReactJS的NetCore2应用程序。 null VS代码抛出一个错误,告诉我异步只适用于。ts文件。另外,如果我在任何其他函数中使用await,我将得到一个错误,比如。 据我所知,async/await不仅仅是TS...(或者我错了?)。 谢了!