1

.NET 4.0では、FtpWebRequest非同期メソッドを使用しています。

私が遭遇している問題の1つは、タイムアウトオプションが必要なことです。

これを実現するために、現在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、あるいはタイムアウトを強制するためのより優れたより信頼できる方法はありますか?

ありがとう

4

1 に答える 1

0

単純にFtpWebRequest.TimeOut プロパティを使用することを検討しましたか?

次の方向の何か:

          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 メソッドが呼び出されるため、うまくいくはずです。

于 2012-07-24T17:22:56.627 に答える