ما هي أفضل طريقة لتمرير البيانات بين سلاسل المحادثات المتزامنة في .NET؟

StackOverflow https://stackoverflow.com/questions/106979

سؤال

لدي موضوعين، يحتاج أحدهما إلى استطلاع مجموعة من الموارد الثابتة المنفصلة للبحث عن التحديثات.والآخر يحتاج إلى الحصول على البيانات وتخزينها في قاعدة البيانات.كيف يمكن للخيط 1 أن يخبر الخيط 2 أن هناك شيئًا ما يجب معالجته؟

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

المحلول

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

على سبيل المثال (من MSDN):

    TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42);

    // Queue the task and data.
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) {    
        Console.WriteLine("Main thread does some work, then sleeps.");

        // If you comment out the Sleep, the main thread exits before
        // the ThreadPool task has a chance to run.  ThreadPool uses 
        // background threads, which do not keep the application 
        // running.  (This is a simple example of a race condition.)
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }
    else {
        Console.WriteLine("Unable to queue ThreadPool request."); 
    }


// The thread procedure performs the independent task, in this case
// formatting and printing a very simple report.
//
static void ThreadProc(Object stateInfo) {
    TaskInfo ti = (TaskInfo) stateInfo;
    Console.WriteLine(ti.Boilerplate, ti.Value); 
}

نصائح أخرى

أستخدم Monitor.Wait / Pulse في قائمة انتظار عناصر العمل.

هل يجب دائمًا تشغيل مؤشر ترابط "المتجر في قاعدة البيانات"؟يبدو أن الخيار الأفضل (إن أمكن) هو جعل مؤشر ترابط الاستقصاء يدور حول مؤشر ترابط آخر للقيام بالحفظ.اعتمادًا على عدد سلاسل الرسائل التي يتم إنشاؤها، قد يكون استخدام مؤشر ترابط الاستقصاء الأول ThreadPool.QueueUserWorkItem() هو المسار الأكثر كفاءة.

لمزيد من الكفاءة، عند الحفظ في قاعدة البيانات، سأستخدم الإدخال/الإخراج غير المتزامن في قاعدة البيانات بدلاً من طرق المزامنة.

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

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

حظ سعيد!

أنا شخصياً سأقوم برفع أحداث الموضوع 1 والتي يمكن للموضوع 2 الرد عليها.يمكن توصيل الخيوط بالأحداث المناسبة من خلال عملية التحكم التي تبدأ كلا الخيوط.

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