Как распараллелить выполнение обработчика событий в C#



У меня есть устройство Kinect, и я разрабатываю программу с его помощью, используя C#.



Для управления устройством я использовал событие AllFramesReady для обработки информации о глубине и цвете.



Я создал обработчик событий для обработки данных, который называется EventHandler1. Я делаю много обработки внутри этого обработчика событий.



Я хотел бы сделать еще несколько вычислений внутри второго обработчика событий с именем EventHandler2.



Можно ли запустить эти 2 обработчика событий какие в основном 2 функции на параллельных, на 2 разных потоках основного процесса? Если возможно, не могли бы вы дать мне пример кода для этого?

619   1  

1 ответ:

Это достаточно легко обернуть в класс; однако вам нужно объединить все обработчики событий в один обработчик событий, прежде чем подписываться на желаемое событие.

Вот быстрый и грязный класс, чтобы продемонстрировать это. Первое предоставленное событие выполняется параллельно с вызовом события, в то время как все остальные выполняются в пуле потоков по умолчанию.

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, предоставляя ему все обработчики событий, которые мы хотим запустить параллельно. Тогда мы ... подпишитесь на событие '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

Наконец, вы должны знать о других проблемах, связанных с многопоточным кодом. Любое общее состояние, изменяемое теперь, должно быть синхронизировано и т. д.

С небольшой работой вы могли бы адаптировать вышеупомянутый класс, чтобы выставить событие, чтобы слушатели могли подписаться и отписаться по своему желанию. Затем в методе обработчика вы извлекли бы список делегатов через Delgate.GetInvocationList (). После того, как у вас есть список делегатов, вы можете обработать их так же, как существующий метод обработчика выше.

Comments

    Ничего не найдено.