2011-09-10 31 views
5

Tôi có đoạn mã này để thực hiện một yêu cầu HTTP không đồng bộ:công tác fromAsync timeout

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

     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(); 
      }); 
    } 

Nó hoạt động, nhưng tôi cần phải thiết lập một thời gian chờ yêu cầu. Tôi đã cố gắng sử dụng request.Timeout nhưng dường như không làm gì cả. Có cách nào để thiết lập thời gian chờ của tác vụ trong mã này không?

Đã chỉnh sửa để thêm cuộc gọi lại thời gian chờ mới. Code mới:

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(); 
      } 
     } 
    } 

thử nghiệm với:

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

Trả lời

8

Từ Timeout documentation:

Thuộc tính Timeout không ảnh hưởng đến yêu cầu không đồng bộ được thực hiện với các BeginGetResponse hoặc BeginGetRequestStream phương pháp.

Điều này là do khuôn khổ buộc bạn tự xử lý thời gian chờ. Bạn có thể sử dụng example code here, ngoại trừ vượt qua Task được trả về từ cuộc gọi FromAsync đến phương thức ThreadPool.RegisterWaitForSingleObject.


Edit:

Bạn cần phải đặt việc đăng ký vào các nhiệm vụ ban đầu, không phải là sự tiếp nối:

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(); 
    }); 
} 

này làm việc cho tôi (nếu tôi đặt thời gian timeout rất ngắn, và nhấn này, tôi luôn luôn thời gian chờ một cách thích hợp).

+0

Tôi đã thay đổi mã như bạn có thể thấy trong câu hỏi nhưng thời gian chờ không hoạt động. Tôi chỉ nhận được một cuộc gọi lại với timedOut sai và sau đó không có gì xảy ra. –

+0

@ David: Tôi đưa vào một số mã số làm việc ... –

+0

Tôi không thể làm cho nó hoạt động. Tôi có một thread.sleep trong phương pháp chính. Có thể là vấn đề này? Tôi đã cập nhật bài đăng để hiển thị cho bạn mã mà tôi đang sử dụng để kiểm tra. –