如果你不控制触发事件的代码,你就别无选择;在这么短的时间内没有办法使用线程池线程。
如果您确实控制了触发事件的代码,您可以选择确保事件处理程序都在 UI 线程中运行。虽然这当然是可能的,但您应该仔细考虑是否应该如此。对于某些事件处理程序来说,让它们在 UI 线程中运行才有意义(例如,大多数事件Form
在 UI 线程中运行),而有些则不然。如果您的事件在 UI 控件上,那么它在 UI 线程中运行可能是有意义的。如果这是您目前恰好从 UI 线程使用的某个工作类的事件,那么在 UI 线程中触发该事件可能是个坏主意(因为您将来可能会使用该工作上下文在非 WPF 上下文中)。
如果您确实想在 UI 线程中触发事件,这很简单。如果您在打算触发事件时已经在 UI 线程中,只需同步调用它:
var eventCopy = MyEvent;
if(eventCopy != null) eventCopy();
如果您希望触发事件时不在 UI 线程中,则在调用上述代码之前编组到 UI 线程:
Dispatcher.BeginInvoke(()=>{ //Or just `Invoke`, if that's appropriate in context
var eventCopy = MyEvent;
if(eventCopy != null) eventCopy();
});
根据您的编辑,您似乎希望根据某些特定上下文有条件地在 UI 线程或线程池线程中触发事件,而不是始终在 UI 线程中触发。
虽然这是可能的,但您需要决定是否值得。
作为示例,您可以查看System.Timers.Timer
哪个具有SynchronizingObject
允许您确定事件如何引发的属性(null
对于线程池,或者在特定 UI 模型的事件中能够编组到特定上下文的对象)。
您可以遵循该一般模式。
具体方法有很多。您可以在SynchronizationContext.Current
首次创建工作线程时捕获该值,并使用它(如果您可能需要禁用它或强制启用它,可能使用布尔值来禁用捕获源同步上下文)。
另一种选择是只拥有一个接受 a 的属性SynchronizationContext
,或者其他一些将代码编组到给定上下文的机制(您可以发明自己的,使用委托等)。