有没有办法在指定的线程上执行回调?

时间:2011-09-24 01:52:09

标签: c# .net multithreading

我正在编写一个库,并且希望能够在指定的线程上触发回调,因此最终用户不必担心线程安全。

我尝试使用ExecutionContext,但是效果不好,它会在指定的上下文(新线程)中触发,但不会在最初调用该函数的线程上触发。

代码应该像这样工作:

void Connect() {
  // This should be in the same thread ..
  SocketAsyncEventArgs.Completed += eventHandler;
  Socket.ConnectAsync(SocketAsyncEventArgs)
}

void eventHandler() {
  // .. as this
}

2 个答案:

答案 0 :(得分:2)

您不能只在某个现有线程上运行代码。该线程已经在执行其他代码。但是,它可以为您提供一些在其上运行代码的方法。 WPF应用程序中的主线程使用Dispatcher.Invoke()执行此操作。 WinForms应用程序的主线程使用Control.Invoke()

有一种更通用的方法:使用Synchronization.Context.Current。这适用于WPF或WinForms应用程序的主线程,但是会在线程池线程上执行回调。 (除非存在某种自定义同步上下文,我认为这种情况非常罕见。)

但这是你能做的最好的事情。就像我说的那样,你不能在你需要的时候在其他线程上运行你的代码。其他线程中的代码必须允许您这样做。

答案 1 :(得分:1)

这是关于异步函数的事情 - 你无法保证何时会被回调,或者什么线程将运行你的回调函数。考虑一下能够“设置并忘记它”的成本。

无论如何通常不需要那么多的控制。如果你“需要”让一个特定的线程运行你的回调,你真正需要的是回顾为什么这是必要的。如果它需要在UI线程上运行,那就是Control.Invoke。 (由于架构的工作原理,UI线程预计需要处理这些事情,因此控件有一种方法可以传递回调以在该线程上运行。你不能只用任意线程来完成它 - 它们有希望传递一个像这样的回调。)否则,如果你遇到锁或其他问题,你可能正在尝试使用异步功能来做一些应该在一个单独的线程中同步完成的东西。