是否有任何方法可以在指定线程上执行回调
本文关键字:线程 执行 回调 任何 方法 是否 | 更新日期: 2023-09-27 18:09:28
我正在编写一个库,并希望能够在指定的线程上触发回调,因此最终用户不必担心线程安全。
我尝试使用ExecutionContext
,但这并没有太好,它会在指定的上下文中(一个新线程)触发,但不是在最初调用函数的线程上。
代码应该是这样工作的:
void Connect() {
// This should be in the same thread ..
SocketAsyncEventArgs.Completed += eventHandler;
Socket.ConnectAsync(SocketAsyncEventArgs)
}
void eventHandler() {
// .. as this
}
您不能在某个现有线程上运行代码。该线程已经在执行其他代码。但是,它可以为您提供一些在其上运行代码的方法。WPF应用程序中的主线程使用Dispatcher.Invoke()
完成此操作。WinForms应用程序的主线程使用Control.Invoke()
.
有一种更通用的方法:使用Synchronization.Context.Current
。这将适用于WPF或WinForms应用程序的主线程,但否则将在线程池线程上执行回调。(除非有某种自定义同步上下文,我认为这是非常罕见的。)
但这是你能做的最好的。就像我说的,你不能在其他线程上运行你的代码。另一个线程中的代码必须允许你这样做
这就是异步函数的问题——你不能保证什么时候会被回调,或者哪个线程会运行你的回调函数。考虑一下能够"设置它并忘记它"的代价。
通常不需要那么多的控制。如果你"需要"让一个特定的线程运行你的回调,你真正需要做的是回顾一下为什么这样做是必要的。如果它需要在UI线程上运行,有Control.Invoke
。(UI线程预期需要交给的东西去做,因为架构是如何工作的,所以控件有一种方法来传递回调在该线程上运行。你不能对任意线程这样做——它们必须期望被传递回调。)否则,如果您遇到锁或其他问题,那么您可能正在尝试使用异步功能来完成应该在单独的线程中同步完成的事情。