2012-05-12 16 views
16

का प्रतिक्रिया प्राप्त करना मुझे आश्चर्य है कि क्या एक async httpwebrequest की प्रतिक्रिया प्राप्त करने का एक आसान तरीका है।एक असिंक्रोनस HttpWebRequest

मैंने पहले से ही यह प्रश्न here देखा है, लेकिन मैं ऐसा करने की कोशिश कर रहा हूं, एक स्ट्रिंग के रूप में प्रतिक्रिया (जो आम तौर पर जेसन या एक्सएमएल है) को वापस कर देता है, जहां मैं इसे फिर से पार्स कर सकता हूं।

Heres कुछ कोड:

मैं इन दोनों स्थिर यहाँ तरीकों जो मुझे लगता है कि धागा सुरक्षित हैं के रूप में सभी पैरामीटर में पारित कर रहे हैं और वहाँ कोई साझा स्थानीय चर कि तरीकों का उपयोग कर रहे हैं है?

public static void MakeAsyncRequest(string url, string contentType) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    request.ContentType = contentType; 
    request.Method = WebRequestMethods.Http.Get; 
    request.Timeout = 20000; 
    request.Proxy = null; 

    request.BeginGetResponse(new AsyncCallback(ReadCallback), request); 
} 

private static void ReadCallback(IAsyncResult asyncResult) 
{ 
    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState; 
    try 
    { 
     using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult)) 
     { 
      Stream responseStream = response.GetResponseStream(); 
      using (StreamReader sr = new StreamReader(responseStream)) 
      { 
       //Need to return this response 
       string strContent = sr.ReadToEnd(); 
      } 
     } 
     manualResetEvent.Set(); 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 
+0

कोड आप ठीक काम तैनात एक बार मैं बाहरी ManualResetEvent हटा दिया।सेट(); - आपको क्या समस्या है? –

+0

@ जेम्समैनिंग हाय ये एक टाइपो था, मैं परिणाम प्राप्त करने के लिए एक आसान तरीका के बाद हूं। आपने जो प्रदान किया है (कार्य ) बिल्कुल लाइनों के साथ है। मैंने सिंक्रोनस अनुरोधों से केवल छलांग लगाई है, ऐसा लगता है जैसे बहुत कुछ चल रहा है। धन्यवाद – gdp

उत्तर

38

समस्या का मानना ​​है कि आपको लौटाई गई सामग्री में कठिन समय मिल रहा है, तो सबसे आसान तरीका एसिंक/प्रतीक्षा का उपयोग कर रहा है यदि आप इसका उपयोग कर सकते हैं। यदि आप .NET 4.5 का उपयोग कर रहे हैं तो यह HttpClient पर स्विच करना बेहतर होगा क्योंकि यह 'मूल रूप से' async है।

.NET 4 और C# 4 का उपयोग करके, आप अभी भी इन्हें लपेटने के लिए कार्य का उपयोग कर सकते हैं और अंतिम परिणाम तक पहुंचने में थोड़ा आसान बना सकते हैं। उदाहरण के लिए, एक विकल्प नीचे होगा। ध्यान दें कि सामग्री स्ट्रिंग उपलब्ध होने तक मुख्य विधि अवरुद्ध हो रही है, लेकिन 'वास्तविक' परिदृश्य में आप शायद किसी अन्य चीज़ को कार्य पास कर दें या किसी अन्य को जारी रखें, इसके बिना या जो भी हो।

void Main() 
{ 
    var task = MakeAsyncRequest("http://www.google.com", "text/html"); 
    Console.WriteLine ("Got response of {0}", task.Result); 
} 

// Define other methods and classes here 
public static Task<string> MakeAsyncRequest(string url, string contentType) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    request.ContentType = contentType; 
    request.Method = WebRequestMethods.Http.Get; 
    request.Timeout = 20000; 
    request.Proxy = null; 

    Task<WebResponse> task = Task.Factory.FromAsync(
     request.BeginGetResponse, 
     asyncResult => request.EndGetResponse(asyncResult), 
     (object)null); 

    return task.ContinueWith(t => ReadStreamFromResponse(t.Result)); 
} 

private static string ReadStreamFromResponse(WebResponse response) 
{ 
    using (Stream responseStream = response.GetResponseStream()) 
    using (StreamReader sr = new StreamReader(responseStream)) 
    { 
     //Need to return this response 
     string strContent = sr.ReadToEnd(); 
     return strContent; 
    } 
} 
+0

आपके उत्तर और समय के लिए फिर से धन्यवाद। – gdp

+0

एक त्वरित प्रश्न, MakeAsyncRequest() विधियों तक पहुंचने पर संपत्ति का परिणाम मैं कैसे सुनिश्चित कर सकता हूं कि जब तक मैं प्रतिक्रिया का उपयोग करने का प्रयास करता हूं तब तक परिणाम हमेशा समाप्त होता है। – gdp

+0

परिणाम संपत्ति तब तक अवरुद्ध होगी जब तक कि यह पहले से नहीं है। –

2

एक बार जब आप async जाते हैं, आप वापस जाने के लिए कभी नहीं कर सकते हैं। वहां से आप केवल असींक के कॉलबैक तक पहुंच सकते हैं। आप इसकी जटिलता को बढ़ा सकते हैं और कुछ थ्रेडिंग & वाइंडैंडल्स कर सकते हैं लेकिन यह एक दर्दनाक प्रयास हो सकता है।

तकनीकी रूप से, जब आप परिणामों की प्रतीक्षा करने की आवश्यकता होती है तो आप थ्रेड भी सो सकते हैं, लेकिन मैं इसकी अनुशंसा नहीं करता हूं, आप उस बिंदु पर एक सामान्य http अनुरोध भी कर सकते हैं।

सी # 5 में async/प्रतीक्षा आदेशों को छोड़ दें जो मुख्य थ्रेड पर एसिंक कॉल के परिणाम प्राप्त करना आसान बना देगा।

+0

धागा वह है जो मुझे अपने सिर को पाने के लिए मिला है। आपके सहयोग के लिए धन्यवाद। – gdp

5

"और भी बेहतर HttpClient करने के लिए स्विच करने के लिए आप .NET 4.5 उपयोग कर रहे हैं, क्योंकि यह है 'मूल रूप से' async होगा।" - जेम्स मैनिंग द्वारा बिल्कुल सही जवाब। इस प्रश्न को 2 साल पहले पूछा गया था। अब हमारे पास .NET Framework 4.5 है, जो शक्तिशाली असीमित तरीकों को प्रदान करता है। HttpClient का प्रयोग करें। निम्नलिखित कोड पर विचार करें:

async Task<string> HttpGetAsync(string URI) 
    { 
     try 
     { 
      HttpClient hc = new HttpClient(); 
      Task<Stream> result = hc.GetStreamAsync(URI); 

      Stream vs = await result; 
      StreamReader am = new StreamReader(vs); 

      return await am.ReadToEndAsync(); 
     } 
     catch (WebException ex) 
     { 
      switch (ex.Status) 
      { 
       case WebExceptionStatus.NameResolutionFailure: 
        MessageBox.Show("domain_not_found", "ERROR", 
        MessageBoxButtons.OK, MessageBoxIcon.Error); 
       break; 
        //Catch other exceptions here 
      } 
     } 
    } 

HttpGetAsync() का उपयोग करने के लिए, एक नई पद्धति है कि "async" भी बनाते हैं। async की आवश्यकता है, क्योंकि हम उपयोग करने के लिए "का इंतजार है" GetWebPage में की जरूरत है() विधि:

async void GetWebPage(string URI) 
     { 
      string html = await HttpGetAsync(URI); 
      //Do other operations with html code 
     } 

अब आप वेब पेज HTML स्रोत कोड एसिंक्रोनस रूप से प्राप्त करना चाहते हैं, तो बस GetWebPage ("वेब पते के फोन ... ")। यहां तक ​​कि स्ट्रीम पढ़ने भी अतुल्यकालिक है।

नोट: HttpClient .NET Framework 4.5 का उपयोग करने के लिए आवश्यक है। इसके अलावा आपको अपनी परियोजना में System.Net.Http संदर्भ जोड़ने की आवश्यकता है और आसान पहुंच के लिए "using System.Net.Http" भी जोड़ना होगा।

आगे पढ़ने कैसे इस दृष्टिकोण से काम करता है के लिए देखें: http://msdn.microsoft.com/en-us/library/hh191443(v=vs.110).aspx Async की

उपयोग: Async in 4.5: Worth the Await

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