1

我有两个非 UI 线程。

  • 线程 A
  • 线程 B

线程 A 引发一个事件,线程 B 监听这个事件。当执行线程 B 事件侦听器时,它在线程 A 上执行(我认为,因为线程 A 引发了事件)。

我想做的是,能够在线程 A 上引发事件,如果线程 B 正在侦听,则侦听器应该在线程 B 上执行。

像这样的东西:

    private void SomeMethodOnThreadA()
    {
        synchronizationContextOfThreadB.Send(new SendOrPostCallback(o =>
                    {
                        EventXy(this, new EventArgs());
                    }), null);
    }

但这不起作用,因为我的线程是非 UI 线程。

4

2 回答 2

3

线程 B 没有监听事件。可能是添加事件处理程序的线程,但该线程不是正在监听的。

您不能随时告诉当前正在运行的线程去执行其他方法而不是它正在执行的操作。当你开始一个新线程时,你给它一个开始的地方,它只是在那里执行代码直到它完成,仅此而已。

当您在 UI 线程上运行代码时,您可以这样做,因为 UI 线程有一个消息循环。它有一个委托队列,线程正在运行的代码如下所示:

while(!applicationStopped)
{
    Action nextAction = queue.Dequeue();
    nextAction();
}

虽然还有更多内容(例如错误处理),但这是一般的想法。要“在 UI 线程中运行代码”,您只需向队列中添加一个委托,它最终将在 UI 线程中运行。

如果您想在线程 B 中运行代码,您将需要一些类似的机制。您需要有某种委托、队列或其他提供它应该执行的委托的媒介,并且该线程需要检查代表应该运行的那个位置。在一般情况下,这通常是不可行的,除非这个其他线程类似于 UI 线程,因为它只执行从其他位置提供的委托。

于 2013-09-26T14:50:09.260 回答
0

线程不负责接收事件。它是调用事件处理程序的线程。

你可以走两种方式:

1)使用消息队列之类的东西。线程 A 队列是队列的对象(数据对象/操作),线程 B 尝试处理队列中的项目。(Fire and Forget) 所以线程 B 必须监视队列。

2)您可以在该线程上创建一个调度程序并Action在其上调用一个。(我在这里做了一个简单的 DispatcherThread 类:http: //csharp.vanlangen.biz/threading/dispatcherthread/)它将创建一个带有 Dispatcher 的线程,以便您可以对其调用操作。

于 2013-09-26T14:48:18.750 回答