如果您不控制触发事件的代码,您就别无选择;在这么短的时间内无法使用线程池线程。
如果您确实控制了触发事件的代码,您可以选择确保事件处理程序全部在 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 中的值,并使用它(如果您可能需要禁用或强制启用它,可以使用布尔值来禁用捕获源同步上下文)。
另一种选择是只拥有一个接受SynchronizationContext 的属性,或其他一些将代码编组到给定上下文的机制(您可以自己发明、使用委托等)。