سؤال

أنا أكتب خدمة ويب ASP.NET باستخدام C# التي تحتوي على وظيفة DoLookup().لكل استدعاء للدالة DoLookup() أحتاج إلى الكود الخاص بي لتنفيذ استعلامين منفصلين:واحد إلى خدمة ويب أخرى في موقع بعيد والآخر إلى قاعدة بيانات محلية.يجب إكمال كلا الاستعلامين قبل أن أتمكن من تجميع النتائج وإعادتها كرد على طريقة DoLookup.المشكلة التي أتعامل معها هي أنني أريد أن أجعل هذا الأمر فعالاً قدر الإمكان، سواء من حيث وقت الاستجابة أو استخدام الموارد على خادم الويب.نحن نتوقع ما يصل إلى عدة آلاف من الاستفسارات في الساعة.فيما يلي نظرة عامة تقريبية تشبه C# لما لدي حتى الآن:

public class SomeService : System.Web.Services.WebService
{
    public SomeResponse DoLookup()
    {
        // Do the lookup at the remote web service and get the response 
        WebResponse wr = RemoteProvider.DoRemoteLookup();   

        // Do the lookup at the local database and get the response
        DBResponse dbr = DoDatabaseLookup();

        SomeResponse resp = new SomeResponse( wr, dbr);

        return resp;
    }
}

الكود أعلاه يفعل كل شيء بالتسلسل ويعمل بشكل رائع ولكن الآن أريد أن أجعله أكثر قابلية للتطوير.أعلم أنه يمكنني استدعاء وظيفة DoRemoteLookup() بشكل غير متزامن (يحتوي RemoteProvider على أساليب BeginRemoteLookup / EndRemoteLookup) وأنه يمكنني أيضًا إجراء البحث في قاعدة البيانات بشكل غير متزامن باستخدام أساليب BeginExecuteNonQuery / EndExecuteNonQuery.

سؤالي (أخيرًا) هو:كيف يمكنني تشغيل كل من البحث عن خدمة الويب عن بعد والبحث في قاعدة البيانات في وقت واحد على سلاسل رسائل منفصلة والتأكد من اكتمالهما قبل إرجاع الاستجابة؟

السبب وراء رغبتي في تنفيذ كلا الطلبين على سلاسل محادثات منفصلة هو أنه من المحتمل أن يكون لكل منهما أوقات استجابة طويلة (1 أو 2 ثانية) وأرغب في تحرير موارد خادم الويب للتعامل مع الطلبات الأخرى أثناء انتظار الاستجابات .ملاحظة إضافية واحدة - لدي حاليًا بحث عن خدمة الويب عن بعد يعمل بشكل غير متزامن، ولم أرغب في جعل النموذج أعلاه مربكًا للغاية.ما أواجهه هو الحصول على كل من البحث عن الخدمة عن بعد وبدء البحث في قاعدة البيانات في نفس الوقت ومعرفة متى يكتمل كلاهما.

شكرا على أي اقتراحات.

هل كانت مفيدة؟

المحلول

ويمكنك استخدام زوج من AutoResetEvents، واحد لكل موضوع. في نهاية تنفيذ موضوع، يمكنك استدعاء AutoResetEvents.Set() لتشغيل الحدث.

وبعد وضع البيض والمواضيع، يمكنك استخدام WaitAll() مع AutoResetEvents اثنين. سيؤدي هذا إلى موضوع لمنع حتى يتم تعيين كلا الحدثين.

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

MSDN لديه نموذج التعليمات البرمجية بشأن استخدام AutoResetEvent.

نصائح أخرى

يرى طرق خدمة ويب XML غير المتزامنة, كيف:إنشاء أساليب خدمة ويب غير متزامنة و كيف:سلسلة المكالمات غير المتزامنة باستخدام طريقة خدمة الويب.

لكن لاحظ الفقرة الأولى من تلك المقالات:

هذا الموضوع خاص بالتكنولوجيا القديمة.يجب الآن إنشاء خدمات ويب XML وعملاء خدمة ويب XML باستخدام مؤسسة اتصالات ويندوز (WCF).


راجع للشغل، يعد تنفيذ الأشياء بالطريقة التي تقولها هذه المقالات أمرًا مهمًا لأنه يحرر مؤشر ترابط عامل ASP.NET أثناء تشغيل المهمة طويلة الأمد.وإلا، فقد تقوم بحظر مؤشر ترابط العامل، مما يمنعه من خدمة المزيد من الطلبات، ويؤثر على قابلية التوسع.

وعلى افتراض انك يمكن أن يكون لها وظيفة رد لكل من طلب ويب وبحث قاعدة بيانات ثم شيء على طول هذه الخطوط قد تعمل

bool webLookupDone = false;
bool databaseLookupDone = false;

private void FinishedDBLookupCallBack()
{
    databaseLookupDone = true;
    if(webLookupDone)
    {
        FinishMethod();
    }
}

private void FinishedWebLookupCallBack()
{
    webLookupDone = true;
    if(databaseLookupDone)
    {
        FinishMethod();
    }
}

واعتقد انني لم يكن لديك ما يكفي من مندوب لupvote ولا التعليق. لذلك هذا هو التعليق على جون سوندرز الإجابة والتعليق آلان على ذلك.

وأنت بالتأكيد تريد أن تذهب مع الجواب جون إذا كنت تشعر بالقلق إزاء قابلية واستهلاك الموارد.

وهناك نوعان من الاعتبارات هنا: تسريع طلب الفردية، وجعل النظام الخاص بك التعامل مع العديد من الطلبات المتزامنة بكفاءة. الجواب السابق على حد سواء آلان وجون تحقق عن طريق إجراء المكالمات الخارجية في نفس الوقت.

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

ولا تفرخ المواضيع الخاصة بك. المواضيع غالية الثمن، وهناك بالفعل الكثير من المواضيع في IO Threadpool التي من شأنها التعامل مع المكالمات الخارجية بالنسبة لك إذا كنت تستخدم أساليب asynch المقدمة من برنامج .NET Framework.

وwebmethod الخدمة الخاص بك يجب أن يكون asynch كذلك. وإلا سيتم حظر مؤشر ترابط عامل حتى تتم المكالمات الخارجية الخاص بك (انها لا تزال 1-2 ثواني حتى لو أنها تعمل بشكل متواز). وكان لديك فقط 12 المواضيع في التعامل مع الطلبات الواردة وحدة المعالجة المركزية (إذا تم تعيين machine.config الخاص وفقا ل<لأ href = "http://support.microsoft.com/default.aspx؟scid=kb؛en-us؛821268" يختلط = "نوفولو noreferrer"> توصية .) بمعنى كنت على الأكثر تكون قادرة على التعامل مع 12 الطلبات المتزامنة (أضعاف # من وحدات المعالجة المركزية). من ناحية أخرى إذا طريقة الويب الخاص بك هو asynch سيعود الى حد كبير instantenously بيغن وموضوع عاد إلى تجمع ترابط استعداد للتعامل مع طلب وارد آخر، في حين يجري انتظر المكالمات الخارجية الخاصة بك على من ميناء الانتهاء IO، حيث أنها سوف يتم التعامل معها من قبل المواضيع من التجمع موضوع IO، بمجرد عودتهم.

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