我试图通过http://blog.stephencleary.com/2012/02/async-and-await.html理解异步编程的概念 和https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/文章,这些是我的发现:
另外,我试图通过以下代码复制这个概念:
private async void button1_Click(object sender, EventArgs e)
{
Task<int> contentLength = mainMethod();
Console.WriteLine("button_click");
int length = await contentLength;
Console.WriteLine(length);
}
private async Task<int> mainMethod()
{
int contentLength = await AccessWebsiteAync();
Console.WriteLine("main method");
return contentLength;
}
async Task<int> AccessWebsiteAync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
string urlContents = await getStringTask;
return urlContents.Length;
}
output : button_click
main method
40692
根据我的理解和以上输出,这是我的疑惑:
client.GetStringAsync("http://msdn.microsoft.com");
一个昂贵的电话,所以它会被返回给来电者
打印button_click。通话如何知道它是否昂贵?我知道我的理解非常混乱。任何消化?
答案 0 :(得分:3)
我认为最好不要直接阅读async
await
,而是了解异步编程究竟是什么。在Python
中,有一个good article。 .Net
也可能有类似的。
网络呼叫是一种输入/输出操作,它不需要CPU但仍需要时间。如果您要等待它,则浪费您的程序时间(从操作系统调度程序获得的共享)。因此,只需让您的程序创建一个网络套接字,发送请求,在队列中监控并继续,您就会变得聪明且敏感。该程序将持续监视所有使用某些API(如select
排队的套接字并处理相应的回调。
想想你是酒店的接待员。在同步方法中,接待员会接受命令并消失,直到他得到答复。在异步方法中,他只需要您的订单并维护日志。他会经常检查状态,并处理它们。
通话如何知道它是否昂贵?
如果你等待,任何输入/输出限制的东西在时间上都会很昂贵。智能操作系统在您准备好之前不会安排您的程序。因此,如果您要执行某些独立任务,则需要根据该程序编写程序。如果它受CPU限制,那么就不要以异步方式进行。
它在哪里存储昂贵电话的状态?
就您的程序而言,您将其抽象为套接字或文件描述符,并监视它是否已准备就绪。其余部分由操作系统和其他相关服务器完成。
如何在后台执行昂贵的通话?
操作系统完成TCP / IP处理工作,实际计算由网络中的其他服务器完成。
答案 1 :(得分:1)
通话如何知道它是否昂贵?
通话不需要&#34;知道&#34;任何东西。例如,您可以await Task.CompletedTask;
,实际上是NOP。
它在哪里存储了一个密集呼叫的状态......
当方法标记为async
时,编译器会生成一个辅助类。您当地的vars&#39;实现为对象字段等。
如何在后台执行昂贵的通话?
大多数I / O都是异步的。该任务在I/O CompletionPort上排队,并在数据进入时重新安排。
在我们使用async / await之前,我们必须使用回调方法,你的button1_Click()将被编写为2个单独的方法,一个设置I / O操作,另一个设置处理结果。