2012-07-24 95 views
1

在.NET 4.0中,我使用了FtpWebRequest異步方法。如何確保異步方法異步運行?

我遇到的一個問題是,我想要一個超時選項。

要做到這一點,我目前傳遞ManualResetEvent圍繞在異步狀態,然後發起請求後調用ResetEvent.WaitOne(30000),確保布爾響應是真實的(或拋出TimeoutException)。

如果我的異步方法異步運行,我相信這很好,因爲它們從另一個線程開始,我當前的線程繼續到WaitOne,然後完成異步方法或超時觸發。

事情是這樣的:

var ar = state.Request.BeginGetResponse(
    new AsyncCallback(BeginGetResponseCallback), 
    state // has a ManualResetEvent 
); 

// Won't reach here if BeginGetResponse run synchronously 
// as indicated by ar.CompletedSynchronously. 
// The risk is then that BeginGet blocks infinitely 
// without a timeout (as I'm seeing) 

if (!state.ResetEvent.WaitOne((int)5000)) 
    throw new TimeoutException(); 

但是,如果我的異步方法同步運行(由CompletedSynchronously所示),那麼WaitOne永遠達不到,和無限的線程塊。

是否有一種可靠的方法(或許是BackgroundWorker?)以確保Begin/End調用異步發生,或者是一種更好,更可靠的強制執行超時的方式?

感謝

回答

0

你有沒有考慮簡單地使用FtpWebRequest.TimeOut property

在東西的方向:

  FtpWebRequest request = null; 

     request.Timeout = 3000; 

     Func<WebResponse> responseDelegate =() => request.GetResponse(); 

     var asynchRes = responseDelegate.BeginInvoke(null, null); 

     try 
     { 
      responseDelegate.EndInvoke(asynchRes); 
     } 
     catch (TimeoutException e) 
     { 
      // bla 
     } 

試想想它,也儘量指定超時並調用BeginGetResponse,它應該工作,因爲它實際上是調用幕後的同步方法。

+1

不適用於異步方法。 '超時是使用GetResponse方法進行的同步請求等待響應的毫秒數「#: – 2012-07-24 17:32:23

+0

太棒了!您可以用委託包裝此調用並等待其完成。捕獲EndXXX方法的TimeOutException。 – Vitaliy 2012-07-24 18:40:16

+0

我必須使用Begin/End方法出於其他原因(異步不是問題)。我們假設這兩個方法必須被調用。鑑於此,我不確定TimeOutException在您的提案中出現的方式/位置?一些代碼可能會演示你的觀點? – 2012-07-24 18:42:47