我有一个 Kinect 设备,我正在使用 C# 开发一个程序。
为了管理设备,我使用AllFramesReady
了事件来处理深度和颜色信息。
我创建了一个事件处理程序来处理名为EventHandler1
. 我在这个事件处理程序中做了很多处理。
我想在名为EventHandler2
.
是否可以在主进程的 2 个不同线程上运行这 2 个事件处理程序,它们基本上是 2 个并行函数?如果可能的话,你能给我一个示例代码吗?
我有一个 Kinect 设备,我正在使用 C# 开发一个程序。
为了管理设备,我使用AllFramesReady
了事件来处理深度和颜色信息。
我创建了一个事件处理程序来处理名为EventHandler1
. 我在这个事件处理程序中做了很多处理。
我想在名为EventHandler2
.
是否可以在主进程的 2 个不同线程上运行这 2 个事件处理程序,它们基本上是 2 个并行函数?如果可能的话,你能给我一个示例代码吗?
这很容易总结在一个类中;但是,在订阅所需事件之前,您需要将所有事件处理程序聚合到一个事件处理程序中。
这是一个快速而肮脏的课程来证明这一点。提供的第一个事件与事件调用内联运行,而所有其他事件都在默认线程池上执行。
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 方法一样处理它们。