2009-01-30 71 views
0

当我需要控制各种异步操作需要多长时间时,我一直在使用这种模式。我不是专门针对WebRequest(我知道你可以设置timeout属性),我只是用它作为模式的一个例子。这种模式有多糟糕?

 var request = WebRequest.Create(someUri); 

     WebResponse response = null; 
     request.BeginGetResponse(result => 
      { 
       var asyncRequest = (WebRequest)result.AsyncState; 
       response = asyncRequest.EndGetResponse(result); 
      }, request); 

     DateTime timeout = DateTime.Now.AddSeconds(10); 
     while (response == null && DateTime.Now <= timeout) 
     { 
      Thread.Sleep(0); 
     } 
     if (response == null) throw new Exception("Timeout!"); 

无论我读到了Thread.Sleep(),听说这是做baaaad的事情,但我真的不认为这个用例滥用它。

我知道它可能会比正好10秒多一点点,但这对我并不重要。

那么,这是真的一个坏方法来完成我正在完成的,如果是这样,有什么更好的方法来做到这一点?

编辑:也许我应该澄清我“米试图完成

的目的是控制的最长时间花在等待上一个电话,我知道,这违背了一个异步的目的。 。打电话,但我们的目的是永远不会是异步的,我只是把它作为一种手段,当我退出呼叫控制

回答

6

的WaitHandles等方法支持超时,使用喜欢的东西:

var asyncResult = request.BeginGetResponse(... 
    asyncResult.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(10)) 
+0

啊哈!这似乎很明显! – 2009-01-30 14:29:48

0

为了完整性:避免阻塞租用线程,使用System.Threading.Timer。

+0

在代码示例中,我认为所需的行为是阻止当前线程。 – 2009-01-30 08:13:29

1

代码看起来完全没问题。如果api中没有任何内容,它只是一种支持同步呼叫的timeout属性的方法。虽然我应该说你最好用一些WaitHandle类替换这个等待循环,但它会使用更少的资源,我相信会看起来更好。对不起,由于我不知道C#和它的API,所以无法提供解决方案。