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

4

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

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

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

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

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

Дело в том, что я выполняю много вычислений для обоих обработчиков событий и не хочу ждать окончания первого обработчика, чтобы я мог начать выполнение второго обработчика. Я хочу запустить их обоих параллельно. Simon
Не могли бы вы рассказать, что вы подразумеваете под Task.Factory.StartNew ()? Как я могу применить эту вещь к выполнению обработчика событий? Simon
@ Симон заменитьConsole.WriteLine с кодом, который вы хотите выполнить в потоке. L.B
Task.Factory.StartNew(() => Console.WriteLine("aaa")); L.B
Если вы можете поместить свой код в поток, вы можете использовать этоmsdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.80).aspx Likurg

Ваш Ответ

1   ответ
3

однако вам необходимо объединить все обработчики событий в один обработчик событий перед подпиской на желаемое событие.

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

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, предоставляя ему все обработчики событий, которые мы хотим запустить параллельно. Затем мы подписываемся на событие «тест» с помощью метода обработчика класса. Наконец, мы называем событие «тест» и просмотрите вывод. Рассмотрим следующий пример:

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.

+1 за подробное объяснение

Похожие вопросы