سوف قائمة الانتظار ثريادبول وظيفة رد الموقت ل, أحيانا جدولة أكثر من موضوع واحد في نفس الوقت?

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

سؤال

في الكود التالي TimerRecalcStatisticsElapsed يجب أن يكون لديك مثيل واحد فقط من تشغيله.يتم إجراء طرق العامل التي يستدعيها رد الاتصال هذا للتشغيل بالتسلسل, مع تشغيل مؤشر ترابط واحد كحد أقصى في كل مرة.

سؤال الجزء 1:

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

السؤال الجزء 2:

بافتراض أنه من الممكن وضع رد اتصال مؤقت واحد في قائمة الانتظار لأي شيء سوى التنفيذ الفوري, هل هذا يعني أن أي عدد من عمليات الاسترجاعات في سلسلة الرسائل قد يتم تنفيذها بشكل متزامن?

سؤال الجزء 3

بافتراض جزء 2 صحيح, هل هذا يعني أن الرمز أدناه يمكن أن يحتوي على أكثر من رد اتصال واحد يعمل في نفس الوقت?

السبب أنا أسأل لأن هناك عدة آلاف من الحالات من هذه الفئة التي تعمل على خادم متعدد وحدة المعالجة المركزية.أرى أيضا تلف البيانات بما يتفق مع عملية خارج النظام من // Do Work Here.

جانبا

// Do work here يعمل داخليا مع نظام.مجموعات.قاموس وتحرير قيم ذ.كما أنه يزيل بعض المفاتيح لوظيفة لاحقة تسمى بشكل متسلسل.هذه الوظيفة مفقودة مفاتيح (س) التي كانت موجودة سابقا في المكالمة الأولى.أعتقد أن هذا بسبب وجود حالة سباق مع البيان الختامي obj.cleanupdata()

public class SystemTimerTest
   {

    readonly System.Timers.Timer timerRecalcStatistics;
    readonly System.Diagnostics.Stopwatch stopwatchForRecalcStatistics = new System.Diagnostics.Stopwatch();


    public SystemTimerTest(TimeSpan range, DataOverwriteAction action)
    {
        int recalculateStatisticsEveryXMillseconds = 1000;

        timerRecalcStatistics = new System.Timers.Timer(recalculateStatisticsEveryXMillseconds);
        timerRecalcStatistics.AutoReset = true;
        timerRecalcStatistics.Elapsed += new System.Timers.ElapsedEventHandler(TimerRecalcStatisticsElapsed);
        timerRecalcStatistics.Interval = recalculateStatisticsEveryXMillseconds;
        timerRecalcStatistics.Enabled = true;


        this.maxRange = range;
        this.hashRunningTotalDB = new HashRunningTotalDB(action);
        this.hashesByDate = new HashesByDate(action);
        this.dataOverwriteAction = action;
    }


    private void TimerRecalcStatisticsElapsed(object source, System.Timers.ElapsedEventArgs e)
    {
        stopwatchForRecalcStatistics.Start();
        Console.WriteLine("The TimerRecalcStatisticsElapsed event was raised at {0}", e.SignalTime.ToString("o"));

         // DO WORK HERE


        stopwatchForRecalcStatistics.Stop();
        double timeBuffer  = GetInterval(IntervalTypeEnum.NearestSecond, e.SignalTime) - stopwatchForRecalcStatistics.ElapsedMilliseconds;

        if (timeBuffer > 0)
            timerRecalcStatistics.Interval = timeBuffer;
        else
            timerRecalcStatistics.Interval = 1;

        stopwatchForRecalcStatistics.Reset();         
        timerRecalcStatistics.Enabled = true;
    }
 }
هل كانت مفيدة؟

المحلول

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

أد 2) هذا ما يقوله مسن عن الموقت فئة:

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

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

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

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

public class MySynchronizeInvoke : ISynchronizeInvoke
{
    private object SyncObject = new Object();
    private delegate object InvokeDelegate(Delegate method, object[] args);

    public IAsyncResult BeginInvoke(Delegate method, object[] args)
    {
        ElapsedEventHandler handler = (ElapsedEventHandler)method;
        InvokeDelegate D = Invoke;
        return D.BeginInvoke(handler, args, CallbackMethod, null);
    }

    private void CallbackMethod(IAsyncResult ar)
    {
        AsyncResult result = ar as AsyncResult;
        if(result != null)
            ((InvokeDelegate)result.AsyncDelegate).EndInvoke(ar);
    }

    public object EndInvoke(IAsyncResult result)
    {
        result.AsyncWaitHandle.WaitOne();
        return null;
    }

    public object Invoke(Delegate method, object[] args)
    {
        lock(SyncObject)
        {
            ElapsedEventHandler handler = (ElapsedEventHandler)method;
            handler(args[0], (ElapsedEventArgs)args[1]);
            return null;
        }
    }

    public bool InvokeRequired
    {
        get { return true; }
    }
}

نصائح أخرى

من عند الوثائق على النظام.توقيت.الموقت:

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

لذا للإجابة على أسئلتك:

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

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

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

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