2011-09-10 19 views
5

मैं कोड के इस टुकड़े एक अतुल्यकालिक HTTP अनुरोध बनाने के लिए है:टास्क fromAsync समय-समाप्त

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

यह काम करता है, लेकिन मैं एक अनुरोध का समय समाप्त सेट करना होगा। मैंने अनुरोध का उपयोग करने की कोशिश की। टाइमआउट लेकिन कुछ भी नहीं लगता है। क्या इस कोड में कार्य टाइमआउट सेट अप करने का कोई तरीका है?

एक नया टाइमआउट कॉलबैक जोड़ने के लिए संपादित किया गया। नए कोड:

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

Timeout documentation से::

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 विधि पर कॉल करने के बाद पास करने के अलावा 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

मैंने कोड में बदल दिया है जैसा कि आप प्रश्न में देख सकते हैं, लेकिन टाइमआउट काम नहीं कर रहा है। मुझे केवल समय के साथ एक कॉलबैक प्राप्त होता है, लेकिन इसके बाद कुछ भी नहीं होता है। –

+0

@ डेविड: मैंने कुछ कामकाजी कोड डाल दिया ... –

+0

मैं इसे काम नहीं कर सकता। मेरे पास एक विधि है। मुख्य विधि में सो जाओ। क्या यह समस्या हो सकती है? मैंने आपको वह कोड दिखाने के लिए पोस्ट अपडेट किया जिसका उपयोग मैं इसका परीक्षण करने के लिए कर रहा हूं। –

संबंधित मुद्दे