Перемещение связанной с делегатом функции в другой поток - PullRequest
0 голосов
/ 28 апреля 2010

Мы разрабатываем библиотеку на C #, которая связывается с последовательным портом. У нас есть функция, которая предоставляется делегату. Проблема в том, что мы хотим, чтобы он запускался в другом потоке.

Мы попытались создать новый поток (называемый DatafromBot), но продолжаем использовать его следующим образом (первая строка):

comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);

DatafromBot = new Thread(comPort_DataReceived);
DatafromBot.Start();

comPort_DataReceived определяется как:

Thread DatafromBot;
public void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e) {  ... }

Происходят следующие ошибки:

Ошибка 3 Лучший перегруженный метод соответствует «System.Threading.Thread.Thread (System.Threading.ThreadStart)» имеет некоторые недействительные аргументы C: ... \ IR52cLow \ CommunicationManager.cs 180 27 IR52cLow

Ошибка 4 Аргумент '1': невозможно преобразовать из «группы методов» в 'System.Threading.ThreadStart' C: ... \ IR52cLow \ CommunicationManager.cs 180 38 IR52cLow

Любые идеи о том, как мы должны преобразовать это, чтобы заставить его скомпилировать? Обратите внимание, что comPort.DataReceived (обратите внимание на «.» Вместо «_») находится в системной библиотеке и не может быть изменен.

Ответы [ 3 ]

2 голосов
/ 28 апреля 2010

Каждый Delegate имеет метод с именем BeginInvoke(). При вызове этот метод вызывает функцию в новом потоке. Так что вам не нужно делать это явно. Например

public delegate string delegate1(int x);

Delegate1 d1 = new Delegate1(Add);

D1.BeginInvoke(10, null, null);

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

Если вам нужно уведомление о завершении метода, вы можете AsyncCallback класс.

D1.BeginInvoke(10, AsyncCallback(AddComplete), null);

Здесь, когда вторичный поток завершает выполнение, он вызывает метод AddComplete() в своем потоке. Основной поток не ожидает дополнительный поток.

Проверьте MSDN.

1 голос
/ 28 апреля 2010

Это не нормально, событие DataReceived срабатывает, когда SerialPort что-то получает.Вы не можете просто запустить поток и надеяться, что из порта будет что-то читать.

Более того, событие DataReceived уже выполняется в отдельном потоке .Класс SerialPort использует поток пула потоков для запуска события.Использование собственного потока для чтения данных из порта - это нормально, но тогда вы не хотите использовать DataReceived.Вы просто используете блокирующие вызовы, любой из методов ReadXxx () квалифицируется.

0 голосов
/ 28 апреля 2010
new Thread(() => comPort_DataReceived(null, null));

Вы также можете передать аргументы sender и eventargs:

var e = new SerialDataReceivedEventArgs();
new Thread(() => comPort_DataReceived(comPort, e));
...