我一直在思考这个问题。
假设我们使用HttpWebRequest类
有一个简单的异步Web请求class webtest1
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("www.google.com");
public webtest1()
{
this.StartWebRequest();
}
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
}
使用同步操作可以轻松实现同样的目的:
class webtest1
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("www.google.com");
public webtest1()
{
webRequest.GetResponse();
}
}
那么,当更简单的同步操作就足够时,为什么我还想使用更复杂的异步操作呢?要节省系统资源吗?
答案 0 :(得分:9)
如果您在等待对请求的响应时发出异步请求,则可以执行其他操作。如果您提出同步请求,则必须等待,直到您收到回复为止,直到您可以执行其他操作为止。
对于简单的程序和脚本而言,它可能并不重要,实际上在许多情况下,更容易编码和理解同步方法将是更好的设计选择。
但是,对于非平凡的程序,例如桌面应用程序,同步请求会锁定整个应用程序,直到请求完成导致不可接受的用户访问 。
答案 1 :(得分:6)
同步操作将阻止您在等待请求完成或超时时执行任何其他操作。使用异步操作可以让您为用户制作动画,以显示程序正忙,甚至让他们继续使用其他功能区域。
答案 2 :(得分:6)
同步版本更易于编码,但它掩盖了一个非常严重的问题。网络通信或实际上是I / O操作可能会阻塞并延长一段时间。例如,许多网络连接的超时时间为2分钟。
同步执行网络操作意味着您的应用程序和UI将在整个操作期间阻止。一个并不罕见的网络打嗝可能导致您的应用程序阻止几分钟而无法取消。这导致非常不满意的客户。
答案 3 :(得分:4)
当你有更多东西比你有核心时,异步变得特别有用 - 例如,你可能有许多活动的网络请求,一些文件访问操作,几个数据库调用,以及其他一些网络操作(可能是WCF或redis)。如果所有这些都是同步的,那么您将创建大量线程,大量堆栈以及遭受大量上下文切换。如果您可以使用异步API,那么当每个操作执行某些操作时,您通常可以利用池线程。这非常适合高吞吐量服务器环境。拥有多个内核非常棒,但效率更高更好。
在C#5中,通过await
,这不再是你的第二个例子。
答案 4 :(得分:2)
前几天我正在读这篇文章,之前一直在考虑类似的问题:
Performance difference between Synchronous HTTP Handler and Asynchronous HTTP Handler
答案 5 :(得分:1)
1)您坚持使用像Silverlight这样的单线程环境。在这里你别无选择,只能使用异步调用,否则整个用户线程都会锁定。
2)你有很多需要很长时间才能处理的电话。为什么在等待返回时可以阻止你的整个线程继续做其他事情?例如,如果我有五个函数调用,每个函数调用需要5秒,我想立即启动它们并让它们在必要时返回。
3)同步输出中要处理的数据太多。如果我有一个程序将10千兆字节的数据写入控制台并且我想读取输出,我有可能异步地逐行处理。如果我同步执行此操作,那么我将耗尽缓冲区空间并锁定程序。