عن طريق المندوبين مجهول مع صافي ThreadPool.QueueUserWorkItem

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

  •  03-07-2019
  •  | 
  •  

سؤال

وكنت ذاهبا إلى الرد على هذا السؤال، ولكن ترد عليها في وقت سابق وقررت الرد على السؤال والجواب - أو على الأقل ملاحظاتي

عند استخدام مندوب مجهول باسم WaitCallback، حيث يسمى ThreadPool.QueueUserWorkItem في حلقة foreach، يبدو أن يتم تمرير نفس foreach-قيمة واحدة في كل موضوع.

List< Thing > things = MyDb.GetTheThings();
foreach( Thing t in Things)
{
    localLogger.DebugFormat( "About to queue thing [{0}].", t.Id );
    ThreadPool.QueueUserWorkItem(
        delegate()
        {
            try
            {
                WorkWithOneThing( t );
            }
            finally
            {
                Cleanup();
                localLogger.DebugFormat("Thing [{0}] has been queued and run by the delegate.", t.Id ); 
            }
        });
 }

لمجموعة من 16 حالات شيء في أشياء أنا لاحظت أن كل "شيء" التي تم تمريرها إلى WorkWithOneThing تتوافق مع البند الأخير في القائمة "الأشياء".

وأظن أن هذا هو لأن مندوب والوصول إلى 'ر' المتغير الخارجي. علما بأنني أيضا جربت مع مرور الشيء كمعلمة لمندوب مجهول، لكنه بقي سلوك غير صحيح.

عند أعيد الحسبان-رمز لاستخدام أسلوب WaitCallback اسمه ومرت الشيء 'ر' إلى أسلوب، فويلا ... على سبيل المثال i'th الأشياء صدر بشكل صحيح في WorkWithOneThing.

وهناك درس في التوازي أعتقد. وأود أيضا أن نتصور أن الأسرة Parallel.For تتناول هذه، ولكن هذه المكتبة ليس خيارا بالنسبة لنا في هذه المرحلة.

وهذا الأمل ينقذ شخص آخر بعض الوقت.

وهوارد هوفمان

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

المحلول

وهذا هو الصحيح، ويصف كيف C # يلتقط المتغيرات الخارجية داخل الإغلاق. انها ليست مباشرة حول قضية التوازي، وإنما حول طرق مجهولة المصدر والعبارات امدا.

يناقش هذا السؤال هذه الميزة لغة وآثارها في التفاصيل.

نصائح أخرى

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

وفيما يلي رابط بالتفصيل لماذا يحدث ذلك. مكتوب عليه لVB لكن C # لديه نفس الدلالة.

HTTP : //blogs.msdn.com/jaredpar/archive/2007/07/26/closures-in-vb-part-5-looping.aspx

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