在.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 :(得分: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
}
想一想,也尝试指定TimeOut并调用BeginGetResponse,它应该可以工作,因为它实际上在后台调用了Synchronous方法。