4

我正在尝试使用FtpWebRequest异步调用(BeginGetResponse/ EndGetResponse)。

但是,似乎来自的回调与BeginGetResponse我的应用程序在同一个线程中运行,当我认为它会使用不同的(和线程池)线程时。这意味着我的应用程序在继续之前会在回调中阻塞。

我已经设置了一个 LINQPad 概念验证,如下所示:

"Starting".Dump();
Thread.CurrentThread.GetHashCode().Dump(); 
Thread.CurrentThread.IsThreadPoolThread.Dump();

IAsyncResult result = request.BeginGetResponse((ar) => 
{
     "Inside Callback".Dump();
     Thread.CurrentThread.GetHashCode().Dump();
     Thread.CurrentThread.IsThreadPoolThread.Dump();
     var resp = request.EndGetResponse(ar);
     "Callback Complete".Dump();
}, null);

"After Callback".Dump();

这将打印输出如下:

Starting
33
False
Inside Callback
33
False
Callback Complete
After Callback

我期望的是这样的(假设回调需要足够长的时间才能运行):

Starting
33
False
Inside Callback
44
True
After Callback // App continues despite callback running
Callback Complete

由于回调在同一个应用程序线程上运行,这意味着如果回调中的某些内容需要很长时间(例如Thread.Sleep,为了参数而引入一个),我的应用程序就会阻塞在那里。这意味着我无法对请求设置超时(例如使用ThreadPool.RegisterWaitForSingleObject)。

我在这里错过了什么吗?

4

2 回答 2

5

当 BeginXXX 方法可以立即完成异步操作时,它不会在线程池线程上运行回调,而是将IAsyncResult.CompletedSynchronously 属性设置为true并同步执行回调。

于 2012-07-02T02:13:21.573 回答
0

我假设 BeginGetResponse 方法在调用者线程的上下文中调用回调

于 2012-07-02T02:06:14.803 回答