سؤال

هو تنفيذ أدناه موضوع آمنة ؟ لو لا ما أنا في عداد المفقودين ؟ يجب أن يكون volatile كلمات في مكان ما ؟ أو قفل في مكان ما في OnProcessingCompleted الطريقة ؟ إذا أين ؟

public abstract class ProcessBase : IProcess
{
    private readonly object completedEventLock = new object();

    private event EventHandler<ProcessCompletedEventArgs> ProcessCompleted;

    event EventHandler<ProcessCompletedEventArgs> IProcess.ProcessCompleted
    {
        add
        {
            lock (completedEventLock)
                ProcessCompleted += value;
        }
        remove
        {
            lock (completedEventLock)
                ProcessCompleted -= value;
        }
    }

    protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
    {
        EventHandler<ProcessCompletedEventArgs> handler = ProcessCompleted;
        if (handler != null)
            handler(this, e);
    }
}

ملاحظة: السبب في أنني قد الحدث الخاص و صريحة واجهة الأشياء لأنها مجردة الفئة الأساسية.و الفئات التي ترث من أنه لا ينبغي أن تفعل أي شيء مع هذا الحدث مباشرة.وأضاف الطبقة المجمع بحيث يكون أكثر وضوحا =)

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

المحلول

هناك حاجة خاصة ProcessCompleted الأعضاء أن يكون event - يمكن أن يكون مجرد حقل: private EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - داخل الصف دائما يذهب مباشرة إلى الميدان ، لذلك event الاشياء المفقودة على أي حال.

نهج لقد أظهرت صريح مع قفل كائن لا كثيرا أكثر من مؤشر الترابط-الآمن من مجرد وجود حقل مثل هذا الحدث (أي public event EventHandler<ProcessCompletedEventArgs> ProcessCompleted; - الفرق الوحيد هو أنك لا تأمين "هذا" (وهو شيء جيد - يجب أن من الناحية المثالية تجنب قفل على this)..في "معالج متغير" النهج الصحيح, ولكن لا يزال هناك الآثار الجانبية يجب أن تكون على علم.

نصائح أخرى

تحتاج إلى قفل عند إحضار معالج أيضا ، وإلا قد لا يكون لديك أحدث القيمة:

protected void OnProcessingCompleted(ProcessCompletedEventArgs e)
{
    EventHandler<ProcessCompletedEventArgs> handler;
    lock (completedEventLock) 
    {
        handler = ProcessCompleted;
    }
    if (handler != null)
        handler(this, e);
}

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

ليس هناك الكثير يمكنك القيام به حيال ذلك, بخلاف جعل المعالج نفسه علم أنه لا ينبغي أن يطلق على أي أكثر.

فإنه يمكن القول إن الأفضل أن لا محاولة لجعل الأحداث مؤشر الترابط-الآمن - تحديد الاشتراك فقط تغيير في الموضوع الذي سوف يرفع الحدث.

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