简体   繁体   English

如何在C#中并行化事件处理程序执行

[英]How to parallelize event handler execution in C#

I have a Kinect device and I am developing a program with it by using C#. 我有一个Kinect设备,我正在使用C#开发一个程序。

In order to manage the device, I have used AllFramesReady event in order to process the depth and color information. 为了管理设备,我使用了AllFramesReady事件来处理深度和颜色信息。

I have created an event handler to process the data which is named EventHandler1 . 我创建了一个事件处理程序来处理名为EventHandler1的数据。 I am doing a lot of processing inside this event handler. 我在这个事件处理程序中做了很多处理。

I would like to do some more computation inside a second event handler named EventHandler2 . 我想在名为EventHandler2的第二个事件处理程序中进行更多计算。

Is it possible to run this 2 event handlers which are basically 2 functions on parallel, on 2 different threads of the main process? 是否可以在主进程的2个不同线程上运行这两个基本上并行2个函数的事件处理程序? If possible, could you please give me a sample code for doing this? 如果可能的话,你能给我一个代码来做这个吗?

This is easy enough to wrap up in a class; 这很容易在课堂上结束; however, you need to aggregate all the event handlers into a single event handler before subscribing to the desired event. 但是,您需要在订阅所需事件之前将所有事件处理程序聚合到单个事件处理程序中。

Here is a quick-and-dirty class to demonstrate this. 这是一个快速而肮脏的课程来演示这一点。 The first event provided runs inline with the event call while all others are executed on the default thread pool. 提供的第一个事件与事件调用一起内联,而所有其他事件在默认线程池上执行。

class ParallelEvent<TEventArg> where TEventArg : EventArgs
{
    private readonly EventHandler<TEventArg> _handler1;
    private readonly EventHandler<TEventArg>[] _moreHandlers;

    public ParallelEvent(EventHandler<TEventArg> handler1, params EventHandler<TEventArg>[] moreHandlers)
    {
        if (handler1 == null)
            throw new ArgumentNullException("handler1");
        if (moreHandlers == null)
            throw new ArgumentNullException("moreHandlers");
        _handler1 = handler1;
        _moreHandlers = moreHandlers;
    }

    public void Handler(Object sender, TEventArg args)
    {
        IAsyncResult[] asyncResults = new IAsyncResult[_moreHandlers.Length];
        for (int i = 0; i < _moreHandlers.Length; i++)
            asyncResults[i] = _moreHandlers[i].BeginInvoke(sender, args, null, null);

        _handler1(sender, args);

        for (int i = 0; i < _moreHandlers.Length; i++)
            _moreHandlers[i].EndInvoke(asyncResults[i]);
    }
}

Now to use this we construct a ParallelEvent class providing it all the event handlers we want to run in parallel. 现在使用它我们构造一个ParallelEvent类,为它提供我们想要并行运行的所有事件处理程序。 Then we subscribe to the event 'test' with the class's Handler method. 然后我们使用类的Handler方法订阅事件'test'。 Finally we call the event 'test' and review the output. 最后,我们将事件称为“测试”并查看输出。 Consider the following example: 请考虑以下示例:

private static event EventHandler<EventArgs> test;

static void Main()
{
    var e = new ParallelEvent<EventArgs>(Test1, Test2);
    test += e.Handler;
    test(null, EventArgs.Empty);
}

static void Test1(Object sender, EventArgs args)
{
    Console.WriteLine("Start Test 1");
    Thread.Sleep(100);
    Console.WriteLine("End Test 1");
}

static void Test2(Object sender, EventArgs args)
{
    Console.WriteLine("Start Test 2");
    Thread.Sleep(100);
    Console.WriteLine("End Test 2");
}

As expected the program above runs them in parallel as demonstrated by the following output: 正如预期的那样,上面的程序并行运行它们,如下面的输出所示:

Start Test 1
Start Test 2
End Test 2
End Test 1

Lastly you need to be aware of other concerns regarding multi-threaded code. 最后,您需要了解有关多线程代码的其他问题。 Any shared state being changed now needs to be synchronized, etc. 任何现在更改的共享状态都需要同步等。

With a little work you could adapt the above class to expose an event so that listeners can subscribe and unsubscribe at will. 通过一些工作,您可以调整上面的类来公开事件,以便侦听器可以随意订阅和取消订阅。 Then in the Handler method you would extract the delegate list via Delgate.GetInvocationList (). 然后在Handler方法中,您将通过Delgate.GetInvocationList ()提取委托列表。 Once you have a list of delegates you can process them the same as the existing Handler method above. 获得委托列表后,您可以像上面现有的Handler方法一样处理它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM