কীভাবে HttpWebRequest (.NET) অবিচ্ছিন্নভাবে ব্যবহার করবেন?


156

আমি কীভাবে HttpWebRequest (.NET, C #) অবিচ্ছিন্নভাবে ব্যবহার করতে পারি?


1
বিকাশকারী ফিউশন এ এই নিবন্ধটি দেখুন: developerfusion.com/code/4654/asynchronous-httpwebrequest

জেসন যা জিজ্ঞাসা করছে তার করণীয়ের পুরোপুরি উদাহরণের জন্য আপনি নিম্নলিখিতটিও দেখতে পারেন: stuff.seans.com/2009/01/05/… শন
শান Sexton


1
এক মুহুর্তের জন্য, আমি ভাবলাম আপনি যদি পুনরাবৃত্ত থ্রেডে মন্তব্য করার চেষ্টা করছেন?
কাইল হজসন

উত্তর:


125

ব্যবহার HttpWebRequest.BeginGetResponse()

HttpWebRequest webRequest;

void StartWebRequest()
{
    webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}

void FinishWebRequest(IAsyncResult result)
{
    webRequest.EndGetResponse(result);
}

অ্যাসিক্রোনাস অপারেশন সম্পূর্ণ হয়ে গেলে কলব্যাক ফাংশন বলা হয়। আপনাকে কমপক্ষে EndGetResponse()এই ফাংশনটি থেকে কল করতে হবে ।


16
অ্যাসিঙ্ক ব্যবহারের জন্য বিগনিগ্রেসপোনস তেমন কার্যকর নয়। এটি সংস্থানটির সাথে যোগাযোগের চেষ্টা করার সময় অবরুদ্ধ বলে মনে হচ্ছে। আপনার নেটওয়ার্ক কেবলটি আনপ্লাগ করার চেষ্টা করুন বা এটিকে একটি ত্রুটিযুক্ত uri দেওয়ার চেষ্টা করুন এবং তারপরে এই কোডটি চালাবেন। পরিবর্তে আপনার সম্ভবত আপনার সরবরাহিত দ্বিতীয় থ্রেডে গেটআরস্পোন চালানো দরকার।
অ্যাশ

2
@ অ্যাশেলিহেন্ডারসন - আপনি কি আমাকে একটি নমুনা সরবরাহ করতে পারেন?
তোহিদ


3
webRequest.Proxy = nullআপনার অনুরোধটি নাটকীয়ভাবে গতিতে যুক্ত করা উচিত ।
ট্রন্টর

সি # আমাকে একটি ত্রুটি ছুঁড়েছে যে এটি একটি অপ্রচলিত শ্রেণি
আলেএক্স_আগস্ট

67

উত্তরটি বিবেচনা করে:

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

গ্রিটিংস


7
'অনুরোধ' ভেরিয়েবলের অতিরিক্ত স্কোপ না করে এমন বিকল্পের জন্য +1, তবে আপনি "হিসাবে" কীওয়ার্ড ব্যবহার না করে একটি কাস্ট তৈরি করতে পারতেন। একটি বিভ্রান্তির পরিবর্তে একটি অবৈধ কাস্টেক্সেক্সেশন নিক্ষেপ করা হবে নুলারফেরান এক্সেপশন
দাভি ফিয়ামেনঝি

64

এখন পর্যন্ত প্রত্যেকেই ভুল হয়েছে, কারণ 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);
});

2
আপনি কি অপেক্ষা করতে ব্যবহার করে এইচটিটিপিউইবরেইকস্টের গেটআরস্পোনএন্সিঙ্ক পদ্ধতিতে কল করতে পারেন না (ধরে নিলেন আপনি নিজের ফাংশনটি অ্যাসিঙ্ক করেছেন)? আমি সি # তে খুব নতুন এসেছি তাই এটি সম্পূর্ণ জিব্বারিশ হতে পারে ...
ব্র্যাড

GetResponseAsync দেখতে দুর্দান্ত দেখাচ্ছে, যদিও আপনার .NET 4.5 প্রয়োজন (বর্তমানে বিটা)।
ইসাক

15
যীশু। এটি কিছু কুরুচিপূর্ণ কোড। অ্যাসিঙ্ক কোডটি কেন পঠনযোগ্য নয়?
জন শেডলেটস্কি

আপনার কেন অনুরোধের দরকার? বেগুনগেটরেস্পোনস ()? কেন মোড়ক অ্যাকশন.বেগিনআইভোক () যথেষ্ট নয়?
ইগোর গ্যাটিস

2
@ গ্যাটিস দুটি স্তরের অ্যাসিনক্রোনাস কল রয়েছে - র‌্যাপারএকশন.বেগিনআইভোকে () ল্যাম্বডা এক্সপ্রেশনটিতে প্রথম অ্যাসিনক্রোনাস কল যা অনুরোধটি কল করে। ইসাক যেমন উল্লেখ করেছেন, বিগনিগেটস্পেস () এর জন্য কিছু সিঙ্ক্রোনাস সেটআপ প্রয়োজন, যে কারণে তিনি এটিকে একটি অতিরিক্ত অ্যাসিঙ্ক্রোনাস কলটিতে আবৃত করেন।
ওয়াকিংটারেজ

64

টিপিএল থেকে টাস্কফ্যাক্টরি ব্যবহার করা 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);
    });

.NET 4 যেহেতু এই ট্যাপের পদ্ধতিটি পছন্দনীয়। এমএস থেকে অনুরূপ উদাহরণ দেখুন - "কীভাবে: কোনও কার্যে ইএপি প্যাটার্নগুলি মোড়ানো" ( এমএসডিএন.মাইক্রোসফটকম /en-us/library/ee622454.aspx )
অ্যালেক্স ক্লাউস

অন্যান্য উপায়ের চেয়ে সহজ উপায়
ডন রোলিং

8

আমি ব্যাকগ্রাউন্ড ওয়ার্কার ব্যবহার করে শেষ করেছি, এটি অবশ্যই উপরোক্ত কয়েকটি সমাধানের বিপরীতে অবিচ্ছিন্ন, এটি আপনার জন্য জিইউআই থ্রেডে ফিরে আসার বিষয়টি পরিচালনা করে এবং এটি বুঝতে খুব সহজ।

ব্যতিক্রমগুলি পরিচালনা করা খুব সহজ, কারণ এগুলি রান ওয়ার্কার কমপ্লিট পদ্ধতিতে শেষ হয় তবে আপনি এটি পড়েছেন তা নিশ্চিত করুন: ব্যাকগ্রাউন্ড ব্যতিক্রম

আমি ওয়েবক্লিয়েন্ট ব্যবহার করেছি তবে আপনি চাইলে আপনি 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();

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

6

এই উত্তরগুলির অনেকগুলি পোস্ট করার পরে .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()উপযুক্ত যেখানে পদ্ধতিগুলি কল করে না । @ ডিগ্রানসারের একটি ভাল বিকল্প সমাধান রয়েছে যা এই সমস্যাগুলিকে সম্বোধন করে।


1
ধন্যবাদ ! একটি অ্যাসিঙ্ক উদাহরণ খুঁজে পেতে চেষ্টা করা হয়েছে, পুরানো পদ্ধতির ব্যবহার যা প্রচুর জটিল using
ডাব্লুডিইউ

এটি কি প্রতিটি প্রতিক্রিয়ার জন্য কোনও থ্রেড আটকাবে না? ডেস্ক.মাইক্রোসফট.ইন
পিট

@ পেটকিরখাম একটি পটভূমি থ্রেড অনুরোধটি করছে, ইউআই থ্রেড নয়। লক্ষ্যটি হ'ল ইউআই থ্রেডটি ব্লক করা এড়ানো। আপনি অনুরোধ করার জন্য যে কোনও পদ্ধতি চয়ন করেছেন তা অনুরোধটি করা থ্রেডটিকে ব্লক করবে। মাইক্রোসফ্ট উদাহরণস্বরূপ আপনি উল্লেখ করেছেন একাধিক অনুরোধ করার চেষ্টা করছে তবে তারা এখনও অনুরোধগুলির জন্য একটি কার্য (একটি পটভূমি থ্রেড) তৈরি করছে।
ট্রোনম্যান

3
পরিষ্কার হওয়ার জন্য, এটি 100% সিঙ্ক্রোনাস / ব্লকিং কোড। অ্যাসিঙ্ক ব্যবহার করতে, WebRequest.GetResponseAsync()এবং StreamReader.ReadToEndAync()ব্যবহার এবং প্রতীক্ষিত হওয়া প্রয়োজন।
রিচার্ড জাজলে

4
@ ট্রোনম্যান যখন অ্যাসিঙ্ক সমতুল্য থাকে তখন কোনও কার্যক্রমে ব্লকিং পদ্ধতিগুলি চালানো একটি অত্যন্ত নিরুৎসাহিত এন্টি-প্যাটার্ন। যদিও এটি কলিং থ্রেডটিকে অবরোধ মুক্ত করে না, ওয়েব হোস্টিং পরিস্থিতিগুলির জন্য এটি স্কেল করার জন্য কিছুই করে না কারণ আপনি কেবল অ্যাসিক্রোনারি অর্জনের জন্য আইও সমাপ্তি বন্দর ব্যবহার না করে কাজটি অন্য থ্রেডে নিয়ে যাচ্ছেন।
রিচার্ড জাজলে

3
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);
        } 
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.