像FileSystemEventHandler
與FileSystemWatcher
類相關的事件處理程序是否可以在不同的線程中同時調用(相互平行)?是否有任何保證?.NET框架中的事件處理程序和多線程處理
回答
一般來說,沒有保證。
事件處理程序在它所調用的同一個線程上運行,但並不真正告訴你任何事情 - 對於你所知道的,它可以用ThreadPool.QueueUserWorkItem(() => EventHandler())
之類的東西調用。 System.Timers.Timer
就是一個例子 - 定時器回調在線程池線程上調用,並且多個可以並行運行。
主要的例外情況是某些同步上下文使用的事件 - 例如,Windows窗體中的GUI事件(包括System.Windows.Forms.Timer
)只會在GUI線程上啓動。但是,文檔應明確指定事件處理程序具有某種特定的線程關聯 - 它當然不是默認假設。
FileSystemWatcher
特別是更棘手。如果它有一個SynchronizingObject
集合,它將具有線程關聯 - 將在同步對象上調用處理程序。例如,如果該同步對象是Form
,則處理程序將始終在GUI線程上運行,並且永遠不會並行運行。其他同步對象的行爲可能會有所不同(例如,您始終可以創建自己的同步對象,將代理髮布到線程池)。請注意,調用是異步的 - 它確實是BeginInvoke
,而不是Invoke
- 所以如果您的同步對象執行類似ThreadPool.QueueUserWorkItem
的操作,它可能會導致並行執行。
如果沒有同步對象,則處理程序在接收通知的同一個線程上運行。由於FileSystemWatcher
在IOCP上運行,假設它只是在回調期間借用一個線程池線程是非常安全的。 但是,它也顯式地在整個代碼周圍,包括事件處理程序調用 - 所以它不會並行運行。
add
和remove
FileSystemWatcher
類的處理程序沒有什麼特別的 - 因爲在大多數情況下 - 它是完全無關緊要的,從哪個線程訂閱一個方法。如果您設置了FileSystemWatcher.SynchronizingObject
,則將通過BeginInvoke
調用在該對象上調用委託;否則, 它將在您的FileSystemWatcher
所在的地方調用。
委託的方法將在調用者的線程中相互調用,因此它們之間沒有同步問題。但是,如果在其他線程中使用了訂閱方法的公共資源,則必須像往常一樣照顧同步。
- 1. 處理多線程事件
- 2. C#,事件處理程序和線程
- 3. .NET事件處理程序管理
- 4. 了JavaFx任務事件處理程序中處理該線程
- 5. C++中的多線程事件處理
- 6. Java中的線程和事件處理
- 7. 幫助理解.NET代表,事件和事件處理程序
- 8. 線程事件處理程序
- 9. 使用backgroundworker和事件處理程序的多線程
- 10. 線程處理事件被處理程序阻塞了?
- 11. HTML事件處理程序與React事件處理程序
- 12. 處理程序不處理事件
- 13. Reactive extensions處理事件處理程序
- 14. 線程事件處理(C#)
- 15. 帶線程事件處理
- 16. C#線程處理事件
- 17. .Net事件處理程序優先
- 18. NServiceBus處理程序中的多線程
- 19. JavaScript圖片加載線程和事件處理程序線程
- 20. Qt中帶多線程的事件處理程序
- 21. C#事件和事件處理程序
- 22. 多線程事件處理請求
- 23. 的事件處理程序
- 24. Android中的處理程序和線程
- 25. Java事件處理框架
- 26. 多線程處理?
- 27. 多線程處理
- 28. matplotlib和python多線程/多處理文件處理
- 29. 事件處理中事件處理程序乘以
- 30. GWT - 如何處理同一事件的多個處理程序