2011-09-10 3 views
5

시간 초과. request.Timeout을 사용하려고했지만 아무 것도하지 않는 것 같습니다. 이 코드에서 작업 제한 시간을 설정하는 방법이 있습니까?작업 fromAsync 내가 비동기 HTTP 요청을하는 코드의 조각이

새 제한 시간 콜백을 추가하기 위해 편집 됨. 새로운 코드 : Timeout documentation에서

HttpSocket.MakeRequest(new Uri("http://www.google.comhklhlñ"), callbackState => 
    { 
     if (callbackState.Exception != null) 
      throw callbackState.Exception; 
     Console.WriteLine(GetResponseText(callbackState.ResponseStream)); 
    }); 
Thread.Sleep(10000); 

답변

8

:와

public static void MakeRequest(Uri uri, Action<RequestCallbackState> responseCallback) 
    { 
     WebRequest request = WebRequest.Create(uri); 
     request.Proxy = null; 

     IAsyncResult t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null).ContinueWith(task => 
      { 
       WebResponse response = task.Result; 
       Stream responseStream = response.GetResponseStream(); 
       responseCallback(new RequestCallbackState(response.GetResponseStream())); 
       responseStream.Close(); 
       response.Close(); 
      }); 
     ThreadPool.RegisterWaitForSingleObject(t.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), request, 1000, true); 
    } 

    private static void TimeoutCallback(object state, bool timedOut) 
    { 
     if (timedOut) 
     { 
      Console.WriteLine("Timeout"); 
      WebRequest request = (WebRequest)state; 
      if (state != null) 
      { 
       request.Abort(); 
      } 
     } 
    } 

테스트

타임 아웃 속성은 BeginGetResponse 또는 BeginGetRequestStream 방법으로 만든 비동기 요청에 영향을주지 않습니다.

이것은 프레임 워크가 직접 시간 초과를 처리해야하기 때문입니다. ThreadPool.RegisterWaitForSingleObject 메서드로 FromAsync 호출에서 반환 된 Task을 전달하는 것 외에는 example code here을 사용할 수 있어야합니다.


편집 : 당신은 원래 작업에 등록을 둘 필요가

아니라 계속 : 나는 타임 아웃 시간이 매우 짧게 설정하면

public static void MakeRequest(Uri uri, Action<Stream> responseCallback) 
{ 
    WebRequest request = WebRequest.Create(uri); 
    request.Proxy = null; 
    const int TimeoutPeriod = 1000; 

    Task<WebResponse> t = Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null); 
    ThreadPool.RegisterWaitForSingleObject((t as IAsyncResult).AsyncWaitHandle, TimeoutCallback, request, TimeoutPeriod, true); 
    t.ContinueWith(task => 
    { 
     WebResponse response = task.Result; 
     Stream responseStream = response.GetResponseStream(); 
     responseCallback(response.GetResponseStream()); 
     responseStream.Close(); 
     response.Close(); 
    }); 
} 

이 (나를 위해 작동 이걸 치면, 나는 항상 적절하게 타임 아웃한다.)

+0

질문에서 볼 수있는 것처럼 코드가 변경되었지만 시간 초과가 작동하지 않습니다. timedOut false로 콜백 만 받으면 아무 일도 일어나지 않습니다. –

+0

@ David : 일부 작업 코드를 넣었습니다 ... –

+0

나는 그것을 작동시킬 수 없습니다. main 메소드에 thread.sleep이 있습니다. 이게 문제일까요? 나는 그것을 테스트하기 위해 사용하고있는 코드를 보여주기 위해 포스트를 업데이트했다. –