আমি কীভাবে 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()
বর্তমান থ্রেডে কিছু কাজ করে। ডকুমেন্টেশন থেকে :
বিগনিগ্রেসপোনস পদ্ধতিতে এই পদ্ধতিটি অ্যাসিনক্রোনাস হওয়ার আগে (ডিএনএস রেজোলিউশন, প্রক্সি সনাক্তকরণ এবং টিসিপি সকেট সংযোগ, উদাহরণস্বরূপ) সম্পূর্ণ করার জন্য কিছু সিঙ্ক্রোনাস সেটআপ টাস্ক প্রয়োজন। ফলস্বরূপ, এই পদ্ধতিটি কখনই কোনও ইউজার ইন্টারফেস (ইউআই) থ্রেডে কল করা উচিত নয় কারণ কোনও ত্রুটির জন্য ব্যতিক্রম ছড়িয়ে দেওয়ার আগে প্রাথমিক সিঙ্ক্রোনাস সেটআপ কার্য শেষ করতে যথেষ্ট সময় (নেটওয়ার্ক সেটিংসের উপর নির্ভর করে কয়েক মিনিট অবধি) সময় নিতে পারে বা পদ্ধতিটি সফল হয়।
সুতরাং এই অধিকার করতে:
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);
});
টিপিএল থেকে টাস্কফ্যাক্টরি ব্যবহার করা AFromAsync দ্বারা এখন পর্যন্ত সবচেয়ে সহজ উপায় । নতুন 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);
আপনি যদি সি # 5 সংকলক ব্যবহার করতে না পারেন তবে উপরের টাস্ক.কন্টিনিউ পদ্ধতি ব্যবহার করে সম্পন্ন করা যেতে পারে :
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse,
request.EndGetResponse,
null)
.ContinueWith(task =>
{
var response = (HttpWebResponse) task.Result;
Debug.Assert(response.StatusCode == HttpStatusCode.OK);
});
আমি ব্যাকগ্রাউন্ড ওয়ার্কার ব্যবহার করে শেষ করেছি, এটি অবশ্যই উপরোক্ত কয়েকটি সমাধানের বিপরীতে অবিচ্ছিন্ন, এটি আপনার জন্য জিইউআই থ্রেডে ফিরে আসার বিষয়টি পরিচালনা করে এবং এটি বুঝতে খুব সহজ।
ব্যতিক্রমগুলি পরিচালনা করা খুব সহজ, কারণ এগুলি রান ওয়ার্কার কমপ্লিট পদ্ধতিতে শেষ হয় তবে আপনি এটি পড়েছেন তা নিশ্চিত করুন: ব্যাকগ্রাউন্ড ব্যতিক্রম
আমি ওয়েবক্লিয়েন্ট ব্যবহার করেছি তবে আপনি চাইলে আপনি 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 পরিবর্তিত হয়েছে, এবং আমি আরও একটি আপ-টু-ডেট উত্তর সরবরাহ করতে চাই। 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;
}
অ্যাসিঙ্ক পদ্ধতিটি ব্যবহার করতে:
String response = await MakeRequestAsync("http://example.com/");
হালনাগাদ:
এই দ্রবণটি ইউডাব্লুপি অ্যাপ্লিকেশনগুলির জন্য কাজ করে না যা WebRequest.GetResponseAsync()
পরিবর্তে ব্যবহার করে WebRequest.GetResponse()
এবং এটি Dispose()
উপযুক্ত যেখানে পদ্ধতিগুলি কল করে না । @ ডিগ্রানসারের একটি ভাল বিকল্প সমাধান রয়েছে যা এই সমস্যাগুলিকে সম্বোধন করে।
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);
}
}