c# .Net 4.5 Связь между потоками

Я создаю приложение, в котором можно отслеживать некоторые аппаратные средства MCU (показания датчиков и т. д.) в режиме реального времени. Для связи я использую CAN-шину.

По сути, у меня есть 2 потока на данный момент. Один из них является основным потоком, в котором работает графический интерфейс, а другой управляет/отслеживает связь между устройствами. Итак, очевидно, что мне нужно передать данные из потока связи в поток графического интерфейса. Однако каким должен быть правильный способ сделать это? Я знаю, как передать данные вызывающему потоку после завершения работы дочернего потока, но в этом случае поток связи работает все время.

Разумеется, коммуникационная логика представлена ​​отдельным классом (CANManager).

У меня есть несколько собственных идей, однако я хотел бы знать, как "правильно" это сделать.

Заранее спасибо :)


person xnonamex    schedule 22.11.2013    source источник
comment
Однако как это сделать правильно? Возможный дубликат google.com.au/search?q=wpf+invoke+on+main+thread   -  person ta.speot.is    schedule 22.11.2013
comment
Взгляните на класс BackgroundWorker, где вы можете использовать событие «ProgressChanged»: msdn.microsoft.com/en-us/library/ | Поскольку вы используете .NET 4.5, вы также можете использовать класс Task, который позволяет вам продолжить тот же процесс, как только завершится ваш дочерний процесс: msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx   -  person Kai Hartmann    schedule 22.11.2013
comment
Моя первоначальная идея состояла в том, чтобы просто создать класс хранения, который будет содержать все необходимые значения в качестве свойств. поэтому я мог бы асинхронно обновлять эти свойства из моего потока связи, а затем просто привязывать эти свойства к файлу wpf. :)   -  person xnonamex    schedule 22.11.2013
comment
Вы имеете в виду «ViewModel»? :)   -  person Dr. Andrew Burnett-Thompson    schedule 22.11.2013
comment
может быть. как вы могли догадаться, я не специалист по oop и c#, так как мое основное дело — встроенный c. Но может ли это быть вещью? это просто кажется самым простым, если это работает?   -  person xnonamex    schedule 22.11.2013


Ответы (1)


Как правило, на любом языке программирования вам необходимо учитывать архитектуру pub-sub для связи между потоками. Это означает, что для каждого потока A, который хочет отправить сообщение потоку B, вы должны отправить «сообщение» или событие из этого потока в очередь, чтобы быть использованным другим потоком, когда он свободен. Если вы просто погуглите 'перекрестное общение c#', вы найти многочисленные статьи для чтения.

В частности, в .NET способ вызова метода или делегирования в другом (любом) потоке заключается в использовании Контекст синхронизации. Это характерно как для Windows Forms, так и для WPF, тогда как WPF имеет Dispatcher, который отличается от этой платформы и вызывается только в потоке пользовательского интерфейса.

Есть много фреймворков, библиотек, паттернов, доступных для такой техники. Одним из них является библиотека параллельных задач. TPL позволяет вам создавать задачу или задачу и вызывать ее в пуле потоков, пользовательском интерфейсе, том же или конкретном потоке. TPL позволяет распределять потоки с помощью Планировщики. Вы можете использовать встроенные планировщики или создать свои собственные. Планировщики используют SynchronizationContext в своей основе для сортировки потоков.

Одним из особенно интересных шаблонов TPL является возможность запускать делегата в одном потоке, а затем объединять несколько операций в другие потоки, например. при завершении или при ошибке. Я бы посмотрел на шаблон асинхронной задачи и рассмотрите возможность возврата Task из асинхронных методов, чтобы вы могли цепочка на них с помощью ContinueWith.

person Dr. Andrew Burnett-Thompson    schedule 22.11.2013