C#:موضوع آمن الأحداث
-
10-07-2019 - |
سؤال
هو تنفيذ أدناه موضوع آمنة ؟ لو لا ما أنا في عداد المفقودين ؟ يجب أن يكون 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
متغير.
ليس هناك الكثير يمكنك القيام به حيال ذلك, بخلاف جعل المعالج نفسه علم أنه لا ينبغي أن يطلق على أي أكثر.
فإنه يمكن القول إن الأفضل أن لا محاولة لجعل الأحداث مؤشر الترابط-الآمن - تحديد الاشتراك فقط تغيير في الموضوع الذي سوف يرفع الحدث.