2012-07-24 99 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