Многопоточность еще на моем списке дел, так что название может быть совершенно неправильно :)Как синхронизировать обработчики событий
Мой объект слушает последовательный порт, как это:
class MyClass
{
MyOpticalScanner _scanner;
public MyClass()
{
_scanner = new MyOpticalScanner();
_scanner.CodeScanned += CodeScannedEventHandler;
}
private void CodeScannedEventHandler(object sender, CodeScannedEventArgs e)
{
Debug.WriteLine("ThreadID: " + Thread.CurrentThread.ManagedThreadId + " ||| " + e.ScannedCode);
....
// Some code, query the database, etc...
}
}
сканер отправляет заказываемые данные: 001
, 002
, 003
, 004
,, 005
... Но если код в CodeScannedEventHandler занимает слишком много времени для обработки, тогда возникает другое событие, и я получил несогласованный порядок. Debug.WriteLine
в обработчик событий может дать мне это:
ThreadID: 8 ||| 001
ThreadID: 9 ||| 002
ThreadID: 10 ||| 003
ThreadID: 10 ||| 006
ThreadID: 8 ||| 004
ThreadID: 8 ||| 008
ThreadID: 8 ||| 009
ThreadID: 8 ||| 010
ThreadID: 10 ||| 007
ThreadID: 9 ||| 005
Как я могу гарантировать, что каждое новое событие начинает обрабатывать только тогда, когда старый закончится?
Редактировать 1 - Я не сказал вам всего, что я не слушаю COM-порт во время тестирования, вместо этого я создал свой собственный макет. Этот объект (ScannerMock) использует внутренний System.Timer и вызывает событие CodeScanned в событии Timer.OnTick. Может ли проблема быть здесь?
От комментария Hans Passant's answer: У SerialPort есть внутренний замок, который гарантирует, что событие DataReceived не может быть вызвано во время его работы. Должен ли я включить аналогичную блокировку в мой издевательский сканер и как?
Редактировать 2: Я добавил замок в свой объект сканера и поместил в него код, который вызывает мое событие. Похоже, что он работает :)
Почему вы обрабатываете значение в нескольких потоках, то? В любом случае вы всегда можете заблокировать его в сканере, чтобы он запускал только одно событие за раз. –
Я не думаю, что проблема связана с обработчиками событий, поскольку они не являются асинхронными. Метод «scan» - это тот, который выполняется асинхронно, и поскольку обработчик событий приходит из него, похоже, что они также асинхронны, но они НЕ. – Jaider