سؤال

ولدي الصفحة التي تحتاج إلى الجمع بين بيانات من أربعة webrequests مختلفة في قائمة واحدة من العناصر. حاليا، أنا على التوالي هذه بالتتابع، إلحاق لقائمة واحدة، ثم ربط تلك القائمة إلى بلدي مكرر.

ومع ذلك، أود أن تكون قادرة على استدعاء هذه webrequests أربعة بشكل متزامن بحيث يمكن تشغيلها في وقت واحد وتوفيرا للوقت الحمل. للأسف، كل الدروس المتزامن والمقالات رأيت صفقة مع طلب واحد، وذلك باستخدام معالج النهائي لمتابعة المعالجة.

وكيف يمكنني أداء الأربعة (حتى هذا قد يزيد!) في وقت واحد، مع الأخذ في الاعتبار أن لكل نتيجة يجب أن يكون الطعام في قائمة واحدة؟

وشكرا جزيلا!

وتحرير: مبسطة مثال على ما أفعله:

var itm1 = Serialize(GetItems(url1));
list.AddRange(itm1);
var itm2 = Serialize(GetItems(url2));
list.AddRange(itm2); 

string GetItems(string url)
{
     var webRequest = WebRequest.Create(url) as HttpWebRequest;
     var response = webRequest.GetResponse() as HttpWebResponse;

     string retval;
     using (var sr = new StreamReader(response.GetResponseStream()))
     { retval = sr.ReadToEnd(); }
     return retval;
} 
هل كانت مفيدة؟

المحلول

وهذا ينبغي أن يكون حقا بسيطة منذ البيانات النهائية الخاصة بك يعتمد على نتيجة من جميع الطلبات الأربعة.

ما يمكنك القيام به هو إنشاء 4 مندوبين المتزامن تشير كل لطريقة الويب المناسب. القيام BeginInvoke على كل منهم. ومن ثم استخدام WaitHandle إلى الانتظار للجميع. ليست هناك حاجة لاستخدام ظهورهم المكالمة، في قضيتك، كما كنت لا ترغب في الاستمرار في حين يجري تجهيز الطرق على شبكة الإنترنت، وإنما ننتظر حتى جميع طرق الويب الانتهاء التنفيذ.

وفقط بعد أن يتم تنفيذ كافة الأساليب على شبكة الإنترنت، فإن التعليمات البرمجية بعد بيان انتظار تنفيذ. هنا يمكنك الجمع بين 4 النتائج.

وفيما يلي نموذج التعليمات البرمجية أنا وضعت لك:

class Program
    {
        delegate string DelegateCallWebMethod(string arg1, string arg2);

        static void Main(string[] args)
        {
            // Create a delegate list to point to the 4 web methods
            // If the web methods have different signatures you can put them in a common method and call web methods from within
            // If that is not possible you can have an List of DelegateCallWebMethod
            DelegateCallWebMethod del = new DelegateCallWebMethod(CallWebMethod);

            // Create list of IAsyncResults and WaitHandles
            List<IAsyncResult> results = new List<IAsyncResult>();
            List<WaitHandle> waitHandles = new List<WaitHandle>();

            // Call the web methods asynchronously and store the results and waithandles for future use
            for (int counter = 0; counter < 4; )
            {
                IAsyncResult result = del.BeginInvoke("Method ", (++counter).ToString(), null, null);
                results.Add(result);
                waitHandles.Add(result.AsyncWaitHandle);
            }

            // Make sure that further processing is halted until all the web methods are executed
            WaitHandle.WaitAll(waitHandles.ToArray());

            // Get the web response
            string webResponse = String.Empty;
            foreach (IAsyncResult result in results)
            {
                DelegateCallWebMethod invokedDel = (result as AsyncResult).AsyncDelegate as DelegateCallWebMethod;
                webResponse += invokedDel.EndInvoke(result);
            }
        }


        // Web method or a class method that sends web requests
        public static string CallWebMethod(string arg1, string arg2)
        {
            // Code that calls the web method and returns the result

            return arg1 + " " + arg2 + " called\n";
        }

    }

نصائح أخرى

وماذا عن إطلاق كل طلب على موضوع منفصل الخاصة بهم ومن ثم إلحاق النتائج إلى القائمة؟

ويمكنك اختبار هذه التعليمة البرمجية التالية:

وParallel.Invoke (() =>                         {
                            // TODO تشغيل طلباتك ...                         })؛

وتحتاج إلى مرجع ملحقات المتوازية: http://msdn.microsoft.com/en-us/concurrency/bb896007. ASPX

وJosh: بخصوص سؤالك حول إرسال 4 (يحتمل أن تكون أكثر) طلبات متزامنة وتتبع الردود (على سبيل المثال لإطعام في القائمة). يمكنك كتابة 4 طلبات و 4 معالجات ردا على ذلك، ولكن بما انك من المحتمل أن يكون لديك المزيد من الطلبات، يمكنك كتابة حلقة غير متزامن. يتم إجراء الكلاسيكية لحلقة من الحرف الأول، وهو شرط، وزيادة. يمكنك كسر كلاسيكية للحلقة إلى حلقة في حين ويكون لا يزال ما يعادلها. ثم جعل لكم حلقة بينما في وظيفة متكررة. الآن يمكنك ان تجعل من غير المتزامن. أضع بعض النصوص عينة هنا في http://asynchronous.me/ . في الحالة الخاصة بك، حدد للحلقة في الخيارات. إذا كنت ترغب في طلبات ليتم إرسالها في تسلسل، أي طلب واحد بعد الاستجابة السابقة (request1، response1، request2، response2، request3، response3، الخ) ثم اختر الاتصال التسلسلي (أي متتابعة)، ولكن رمز هو أكثر قليلا معقد. من ناحية أخرى، إذا كنت لا تبالي الترتيب الذي وردت ردود (ترتيب عشوائي)، ثم اختر الاتصال الموازي (أي المتزامنة)، رمز هو أكثر بديهية. في كلتا الحالتين، سوف تكون مرتبطة بعضها استجابة لطلب المقابلة عن طريق معرف (عدد صحيح بسيط) حتى تتمكن من تتبع كل منهم. والموقع يوفر لك برنامج نصي عينة. تتم كتابة عينات في جافا سكريبت لكنه ينطبق على أي لغة. تكييف النصي لغتك وتفضيلات الترميز. مع ذلك السيناريو، يرسل المتصفح 4 طلبات بشكل متزامن، والمعرف عليك أن تكون قادرا على تتبع التي تطلب استجابة يناظر. أتمنى أن يساعدك هذا. / تيبو لوبيز شنايدر

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top