c# - 在另一个线程中运行事件处理程序(没有线程阻塞)

标签 c# multithreading event-handling synchronize

我有一个类Communicator在后台线程中工作,在 TCP 端口上接收数据。

Communicator 有一个事件 OnDataReceived这是一个 EventHandler<DataReceivedEventArgs>类型。

还有一个类Consumer包含订阅 Communicator.OnDataReceived 的方法事件。

comm.OnDataReceived += consumer.PresentData;

Consumer类在 Form 构造函数中创建,然后在另一个线程上调用其方法之一。该方法是一个无限循环,因此在应用程序执行期间它一直停留在该方法中。

我想做的是 Communicator.OnDataReceived调用 consumer.PresentData 的事件消费者线程上的方法。

这几乎是可能的吗?如果是,我应该使用什么样的机制(同步类)?

最佳答案

在您的代码中的某处添加它:(我通常将它放在一个名为 ISynchronizedInvoke 的静态帮助程序类中,这样我就可以调用 ISynchronizedInvoke.Invoke(...));

public static void Invoke(ISynchronizeInvoke sync, Action action) {
    if (!sync.InvokeRequired) {
        action();
    }
    else {
        object[] args = new object[] { };
        sync.Invoke(action, args);
    }
}

然后在 OnDataReceived 中,你可以这样做:

Invoke(consumer, () => consumer.PresentData());

这会在“消费者”上调用“消费者.PresentData”。

至于你的设计问题(consumer references communicator),你可以在communicator中引入一个方法,例如:

class Communicator {
    private ISynchronizeInvoke sync;
    private Action syncAction;

    public void SetSync(ISynchronizeInvoke sync, Action action) {
        this.sync = sync;
        this.syncAction = action;
    }

    protected virtual void OnDataReceived(...) {
        if (!sync.InvokeRequired) {
            syncAction();
        }
        else {
            object[] args = new object[] { };
            sync.Invoke(action, args);
        }
    }
}

这将为您提供一种从消费者类传入 ISynchronizedInvoke 的方法。因此,您将在使用者程序集中创建 ISynchronizedInvoke。

class Consumer {
    public void Foo() {
        communicator.SetSync(this, () => this.PresentData());
    }
}

所以基本上您正在创建执行调用所需的一切,并将其传递给您的通信器。这解决了您在通信器中有一个实例或对消费者的引用的必要性。

另请注意,我没有测试任何这些我只是在理论上做这一切,但它应该工作得很好。

关于c# - 在另一个线程中运行事件处理程序(没有线程阻塞),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6615913/

相关文章:

Sharepoint 计时器作业创建列表项但不触发项目事件处理程序

jquery - 加载外部 HTML 并为 HTML 中声明的元素添加事件处理程序

angular - 在 mat-checkbox 中停止 mat-select 的事件传播

c# - ASP.NET MVC 3 : Override "name" attribute with TextBoxFor

c# - 如何跟踪 .Net 线程池的使用情况?

linux - 等待线程如何知道共享资源已被另一个线程解锁?

c++ - 使用 std::mutex 实现信号量

c# - Ion.Sound 1.1.0 JQuery javascript 响应

c# - 几秒钟后如何触发事件?

C# 配对 HTML 标签以检查它们是否正确平衡