2009-03-18 50 views
20

Nếu tôi đang sử dụng EventWaitHandle (hoặc AutoResetEvent, ManualResetEvent) để đồng bộ hóa giữa các chuỗi thì tôi có cần gọi các phương thức Close() hoặc Dispose() trên sự kiện đó khi xử lý xong không?Tôi có cần Vứt bỏ() hoặc Đóng() một EventWaitHandle không?

EventWaitHandle kế thừa từ WaitHandle, triển khai IDisposable. Và FxCop than phiền nếu tôi không triển khai IDisposable trên bất kỳ lớp nào có chứa EventWaitHandle. Vì vậy, điều này cho thấy rằng tôi cần phải gọi nó.

Tuy nhiên không ai trong số những ví dụ sử dụng MSDN gọi Dispose() hoặc Close():

http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(VS.80).aspx

Đây có phải là chỉ là một ví dụ của Microsoft phớt lờ lời khuyên của riêng mình?

Trả lời

20

Tài nguyên dùng một lần của EventWaitHandle thực ra là SafeHandle (được bọc trong SafeWaitHandle). SafeHandle thực hiện trình hoàn thiện, cuối cùng đảm bảo tài nguyên cần thiết được giải phóng, do đó, an toàn để cho trình thu gom/bộ xử lý rác xử lý nó trong trường hợp này là.

Tuy nhiên, bạn nên gọi rõ ràng Dispose() khi tài nguyên không còn cần thiết nữa.

Chương luồng trong C# 3.0 in a Nutshell bang

thực hành này là (cho là) ​​có thể chấp nhận với chờ xử lý vì họ có một gánh nặng OS ánh sáng (không đồng bộ đại biểu dựa vào chính xác cơ chế này để phát hành IAsyncResult của họ ' s chờ đợi xử lý).

+0

Tôi cho rằng việc cho phép GC thu thập nó là khá không mong muốn. Rời khỏi công việc cho chuỗi Finalizer chỉ là thực hành không tốt. Chỉ có một chuỗi finalizer đơn và khiến nó làm nhiều hơn nó thực sự không tốt. Nếu chuỗi bị chặn, ứng dụng của bạn bị treo. Nếu một ngoại lệ được ném vào chuỗi finalizer, AppDomain của bạn bị treo. Có mẫu vứt bỏ thích hợp đảm bảo rằng GC.SuppressFinalize() được gọi là do đó triệt tiêu hoàn thiện đối tượng này. Tôi có một ví dụ về việc triển khai IDisposable - http://dave-black.blogspot.com/2011/03/how-do-you-properly-implement.html –

+0

Tôi đồng ý và đó là lý do tại sao tôi tuyên bố rằng bạn nên gọi rõ ràng 'Vứt bỏ '. –

6

Bạn cần phải vứt bỏ chúng một cách rõ ràng. Close() phù hợp hơn với chúng vì nó gọi Dispose().

2

định nghĩa lớp từ MSDN:

public class EventWaitHandle : WaitHandle 
public abstract class WaitHandle : MarshalByRefObject, IDisposable 

Vì vậy, có bạn phải như WaitHandle là IDisposable. FxCop sẽ thấy điều này là vi phạm quy tắc nếu bạn không làm như vậy.

+0

Cảm ơn Peter, nhưng tại sao ví dụ sử dụng MSDN không gọi là Close() hoặc Dispose()? Đây có phải là Microsoft không theo lời khuyên của riêng họ? – GrahamS

+1

Tôi đoán 50% không theo lời khuyên của riêng họ và 50% cố gắng giữ các ví dụ ngắn gọn nhất có thể .. với một món ăn của những người viết các ví dụ (không phải là nhà phát triển SDK chính) không biết rõ hơn. –

Các vấn đề liên quan