C# 如何确保异步方法异步运行?

C# 如何确保异步方法异步运行?,c#,.net-4.0,asynchronous,C#,.net 4.0,Asynchronous,在.NET4.0中,我使用的是FtpWebRequestasync方法 我遇到的一个问题是我想要一个超时选项 为了实现这一点,我目前正在异步状态下传递一个ManualResetEvent,然后在启动请求后调用ResetEvent.WaitOne(30000),确保布尔响应为true(或抛出TimeoutException) 如果我的异步方法以异步方式运行,我相信这是可以的,因为它们在另一个线程中启动,我的当前线程继续运行到WaitOne,然后异步方法完成或超时触发 大概是这样的: var ar

在.NET4.0中,我使用的是
FtpWebRequest
async方法

我遇到的一个问题是我想要一个超时选项

为了实现这一点,我目前正在异步状态下传递一个
ManualResetEvent
,然后在启动请求后调用
ResetEvent.WaitOne(30000)
,确保布尔响应为true(或抛出
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
调用异步进行,或者有更好、更可靠的方法来强制执行超时


谢谢

您是否考虑过简单地使用

朝以下方向发展的事物:

          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
        }
FtpWebRequest请求=null;
请求超时=3000;
Func responseDelegate=()=>request.GetResponse();
var asynchRes=responseDelegate.BeginInvoke(null,null);
尝试
{
EndInvoke(asynchRes);
}
捕获(超时异常e)
{ 
//布拉
}

想想看,还要尝试指定超时并调用BeginGetResponse,它应该可以工作,因为它实际上在幕后调用同步方法。

不适用于异步方法
Timeout是使用GetResponse方法发出的同步请求等待响应的毫秒数
Great!您可以使用委托包装此调用并等待其完成。捕获EndXXX方法上的TimeOutException。出于其他原因,我不得不使用Begin/End方法(异步不是问题)。让我们假设必须调用这两个方法。考虑到这一点,我不确定TimeOutException是如何/在何处加入到您的提案中的?可能需要一些代码来演示你的观点?谢谢你的代码。不幸的是,我不得不使用
BeginGetResponse
not
GetResponse
,因为它在幕后调用了一些我正在利用的内部回调(即使是
同步完成时,也只能指示哪个线程运行了函数,而不是调用了哪些函数),我相信它也可以用于BeginGetResponse,因为它在幕后调用了同步方法。