为什么要在同步操作中使用异步操作?

为什么要在同步操作中使用异步操作?

问题描述:

我一直在思考这个问题。为什么要在同步操作中使用异步操作?

比方说,我们必须使用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(); 
    } 
} 

那么,为什么我要使用当更简单的同步操作就足够了时,更复杂的异步操作?为了节省系统资源?

+2

因为你喜欢挑战吗? – 2011-12-13 22:51:03

+1

你没有提到你使用的平台,但我可以推断它不是SilverLight。在SL你不会选择。 – 2011-12-13 23:00:13

+1

有趣的是,如果我没有记错的话,异步webrequest方法不是完全异步的,而是阻止部分操作,例如DNS查找。 – CodesInChaos 2011-12-13 23:02:39

同步操作将阻止您在等待请求完成或超时时执行其他任何操作。使用异步操作可让您为用户设置动画,以显示程序繁忙,甚至让他们继续使用其他功能区域。

1)你粘贴到单线程环境例如Silverlight。在这里,你别无选择,只能使用异步调用,否则整个用户线程将被锁定。

2)您有许多需要很长时间处理的呼叫。为什么要阻止你的整个线程,当它可以继续,并等待返回时做其他事情?例如,如果我有五个函数调用,每个调用需要5秒钟,我想立即启动所有函数,并根据需要返回它们。

3)太多要处理的数据的输出同步地。如果我有一个程序可以将10千兆字节的数据写入控制台,并且我想读取输出,那么我有机会异步地逐行处理。如果我同步执行此操作,那么我将耗尽缓冲区空间并锁定程序。

我读这个有一天,类似的问题已经思考之前:同步版本

Performance difference between Synchronous HTTP Handler and Asynchronous HTTP Handler

是简单的代码,但它掩盖了很严重的问题。网络通信或真正的I/O操作可能会阻塞并延长一段时间。例如,许多网络连接的超时时间为2分钟。

同步执行网络操作意味着您的应用程序和UI将在整个操作过程中阻塞。一个不寻常的网络呃逆可能会导致你的应用程序阻塞几分钟而无法取消。这导致非常不满意的客户。当你有更多的东西去上比你有核心

异步变得特别有用 - 例如,你可能有一些活跃的网络请求,一些文件访问操作的,很少DB电话,也许有些其他网络操作(WCF或Redis也许)。如果所有这些都是同步的,你就会创建很多线程,堆栈很多,并且会遇到很多上下文切换。如果您可以使用异步API,那么通常可以利用池线程来处理每个操作某些事情时的短暂时刻。这对高吞吐量服务器环境非常有用。拥有多个核心很棒,但效率更高。

在C#5这成为通过await,比你的第二个例子中,没有更多的工作。

如果您制作异步请求您可以在等待对请求的响应时做其他事情。如果您制作同步请求,您必须等待,直到您收到您的回复,直到您可以执行其他操作。

对于简单的程序和脚本,它可能并不重要,事实上在许多情况下,更容易编码和理解同步方法将是更好的设计选择。

然而,对于非平凡的程序,如桌面应用程序,直到的请求完成导致不可接受的用户经验研究其中锁定了整个应用程序同步请求