मैं HttpWebRequest (.NET, C #) का उपयोग कैसे कर सकता हूं?
मैं HttpWebRequest (.NET, C #) का उपयोग कैसे कर सकता हूं?
जवाबों:
उपयोग HttpWebRequest.BeginGetResponse()
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
कॉलबैक फ़ंक्शन को कहा जाता है जब एसिंक्रोनस ऑपरेशन पूरा होता है। आपको EndGetResponse()इस फ़ंक्शन से कम से कम कॉल करने की आवश्यकता है ।
webRequest.Proxy = nullनाटकीय रूप से अनुरोध को तेज करने के लिए जोड़ना चाहिए ।
उत्तर को ध्यान में रखते हुए:
HttpWebRequest webRequest;
void StartWebRequest()
{
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
webRequest.EndGetResponse(result);
}
आप अनुरोध सूचक या इस तरह की किसी अन्य वस्तु को भेज सकते हैं:
void StartWebRequest()
{
HttpWebRequest webRequest = ...;
webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), webRequest);
}
void FinishWebRequest(IAsyncResult result)
{
HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}
अभिवादन
अब तक हर कोई गलत है, क्योंकि BeginGetResponse()वर्तमान थ्रेड पर कुछ काम करता है। से प्रलेखन :
इस विधि के अतुल्यकालिक होने से पहले, BeginGetResponse विधि को (उदाहरण के लिए, DNS रिज़ॉल्यूशन, प्रॉक्सी पहचान और टीसीपी सॉकेट कनेक्शन) को पूरा करने के लिए कुछ सिंक्रोनस सेटअप कार्यों की आवश्यकता होती है। परिणामस्वरूप, इस विधि को कभी भी उपयोगकर्ता इंटरफ़ेस (UI) थ्रेड पर नहीं बुलाया जाना चाहिए क्योंकि किसी त्रुटि के लिए अपवाद के पहले प्रारंभिक सिंक्रोनस सेटअप कार्यों को पूरा करने में काफी समय (नेटवर्क सेटिंग्स के आधार पर कई मिनट तक) लग सकता है या विधि सफल होती है।
तो यह सही करने के लिए:
void DoWithResponse(HttpWebRequest request, Action<HttpWebResponse> responseAction)
{
Action wrapperAction = () =>
{
request.BeginGetResponse(new AsyncCallback((iar) =>
{
var response = (HttpWebResponse)((HttpWebRequest)iar.AsyncState).EndGetResponse(iar);
responseAction(response);
}), request);
};
wrapperAction.BeginInvoke(new AsyncCallback((iar) =>
{
var action = (Action)iar.AsyncState;
action.EndInvoke(iar);
}), wrapperAction);
}
आप तब कर सकते हैं जो आपको प्रतिक्रिया के साथ चाहिए। उदाहरण के लिए:
HttpWebRequest request;
// init your request...then:
DoWithResponse(request, (response) => {
var body = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.Write(body);
});
अब तक सबसे आसान तरीका है TPL से TaskFactory.FromAsync का उपयोग करना । जब यह नए async / प्रतीक्षा कीवर्ड के साथ संयोजन में उपयोग किया जाता है तो यह शाब्दिक रूप से कोड की एक जोड़ी है :
var request = WebRequest.Create("http://www.stackoverflow.com");
var response = (HttpWebResponse) await Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null);
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
यदि आप C # 5 संकलक का उपयोग नहीं कर सकते हैं तो ऊपर टास्क को बंद करके पूरा किया जा सकता है। विधि बंद करें:
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null)
.ContinueWith(task =>
{
var response = (HttpWebResponse) task.Result;
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
});
मैंने बैकग्राउंडवॉकर का उपयोग करके समाप्त किया, यह निश्चित रूप से उपरोक्त कुछ समाधानों के विपरीत अतुल्यकालिक है, यह आपके लिए GUI थ्रेड पर वापस लौटता है, और इसे समझना बहुत आसान है।
अपवादों को संभालना भी बहुत आसान है, क्योंकि वे रनवॉकर कम्पीटेड पद्धति में समाप्त हो जाते हैं, लेकिन सुनिश्चित करें कि आप इसे पढ़ते हैं: BackgroundWorker में अनचाहे अपवाद
मैंने WebClient का उपयोग किया है, लेकिन जाहिर है कि यदि आप चाहते थे तो आप HttpWebRequest.GetResponse का उपयोग कर सकते हैं।
var worker = new BackgroundWorker();
worker.DoWork += (sender, args) => {
args.Result = new WebClient().DownloadString(settings.test_url);
};
worker.RunWorkerCompleted += (sender, e) => {
if (e.Error != null) {
connectivityLabel.Text = "Error: " + e.Error.Message;
} else {
connectivityLabel.Text = "Connectivity OK";
Log.d("result:" + e.Result);
}
};
connectivityLabel.Text = "Testing Connectivity";
worker.RunWorkerAsync();
public static async Task<byte[]> GetBytesAsync(string url) {
var request = (HttpWebRequest)WebRequest.Create(url);
using (var response = await request.GetResponseAsync())
using (var content = new MemoryStream())
using (var responseStream = response.GetResponseStream()) {
await responseStream.CopyToAsync(content);
return content.ToArray();
}
}
public static async Task<string> GetStringAsync(string url) {
var bytes = await GetBytesAsync(url);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
इन उत्तरों में से कई पोस्ट किए जाने के बाद .NET बदल गया है, और मैं एक और अप-टू-डेट उत्तर प्रदान करना चाहता हूं। एक async विधि का प्रयोग करें जो Taskकि एक पृष्ठभूमि थ्रेड पर चलेगी:
private async Task<String> MakeRequestAsync(String url)
{
String responseText = await Task.Run(() =>
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
}
return null;
});
return responseText;
}
Async विधि का उपयोग करने के लिए:
String response = await MakeRequestAsync("http://example.com/");
अपडेट करें:
यह समाधान UWP ऐप्स के लिए काम नहीं करता WebRequest.GetResponseAsync()है WebRequest.GetResponse(), जो इसके बजाय उपयोग करते हैं , और यह उन Dispose()तरीकों को कॉल नहीं करता है जहां उपयुक्त है। @dragansr के पास एक अच्छा वैकल्पिक समाधान है जो इन मुद्दों को संबोधित करता है।
WebRequest.GetResponseAsync()और StreamReader.ReadToEndAync()उपयोग करने और प्रतीक्षा करने की आवश्यकता है।
public void GetResponseAsync (HttpWebRequest request, Action<HttpWebResponse> gotResponse)
{
if (request != null) {
request.BeginGetRequestStream ((r) => {
try { // there's a try/catch here because execution path is different from invokation one, exception here may cause a crash
HttpWebResponse response = request.EndGetResponse (r);
if (gotResponse != null)
gotResponse (response);
} catch (Exception x) {
Console.WriteLine ("Unable to get response for '" + request.RequestUri + "' Err: " + x);
}
}, null);
}
}