First - คลาสส่วนใหญ่ไม่จำเป็นต้องเป็น thread-safe ใช้YAGNI : ใช้ความปลอดภัยของเธรดเท่านั้นเมื่อคุณรู้ว่าคุณกำลังใช้งานจริง (และทดสอบ)
สำหรับสิ่งที่ระดับวิธีมี[MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
สิ่งนี้สามารถใช้กับ accessors (คุณสมบัติและเหตุการณ์):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
โปรดทราบว่าเหตุการณ์ที่คล้ายฟิลด์จะซิงโครไนซ์โดยค่าเริ่มต้นในขณะที่คุณสมบัติที่ใช้งานอัตโนมัติจะไม่ :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
โดยส่วนตัวแล้วฉันไม่ชอบการนำไปใช้MethodImpl
เพราะมันล็อคthis
หรือtypeof(Foo)
- ซึ่งขัดกับแนวปฏิบัติที่ดีที่สุด ตัวเลือกที่ต้องการคือการใช้ล็อคของคุณเอง:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
โปรดทราบว่าสำหรับเหตุการณ์ที่คล้ายฟิลด์การดำเนินการล็อกขึ้นอยู่กับคอมไพเลอร์ ในคอมไพเลอร์ Microsoft รุ่นเก่ามันเป็นlock(this)
/ lock(Type)
- อย่างไรก็ตามในคอมไพเลอร์ล่าสุดจะใช้Interlocked
การอัพเดตดังนั้นเธรดที่ปลอดภัยโดยไม่มีส่วนที่น่ารังเกียจ
สิ่งนี้อนุญาตให้ใช้แบบละเอียดมากขึ้นและอนุญาตให้ใช้Monitor.Wait
/ Monitor.Pulse
etc เพื่อสื่อสารระหว่างเธรด
ที่เกี่ยวข้องกับรายการบล็อก (ต่อมาเยือน )