5

我有一个 Kinect 设备,我正在使用 C# 开发一个程序。

为了管理设备,我使用AllFramesReady了事件来处理深度和颜色信息。

我创建了一个事件处理程序来处理名为EventHandler1. 我在这个事件处理程序中做了很多处理。

我想在名为EventHandler2.

是否可以在主进程的 2 个不同线程上运行这 2 个事件处理程序,它们基本上是 2 个并行函数?如果可能的话,你能给我一个示例代码吗?

4

1 回答 1

4

这很容易总结在一个类中;但是,在订阅所需事件之前,您需要将所有事件处理程序聚合到一个事件处理程序中。

这是一个快速而肮脏的课程来证明这一点。提供的第一个事件与事件调用内联运行,而所有其他事件都在默认线程池上执行。

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]);
    }
}

现在要使用它,我们构建一个 ParallelEvent 类,为它提供我们想要并行运行的所有事件处理程序。然后我们使用类的 Handler 方法订阅事件 'test'。最后,我们将事件称为“测试”并查看输出。考虑以下示例:

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");
}

正如预期的那样,上面的程序并行运行它们,如以下输出所示:

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

最后,您需要了解有关多线程代码的其他问题。现在任何正在更改的共享状态都需要同步,等等。

通过一些工作,您可以调整上述类以公开事件,以便侦听器可以随意订阅和取消订阅。然后在 Handler 方法中,您将通过Delgate.GetInvocationList () 提取委托列表。一旦你有了一个委托列表,你就可以像上面现有的 Handler 方法一样处理它们。

于 2012-05-02T16:51:22.030 回答