delegate void eventDelegate (object sender, DataCollectedEventArgs e);
private void dataReceiver1_DataReceived(object sender, DataCollectedEventArgs e)
{
if (this.InvokeRequired)
{
this.Invoke(new eventDelegate(dataReceiver1_DataReceived), new object[] {sender,e});
}else
{
//тут уже можно делать любые манипуляции с интерфейсом и данными
//правда ещё нужно задумываться над потокобезопасностью данного кода
}
}
События (Типа Delphi)
Вопрос: Воббще правильно ли это, или нужно чтоб события обрабатывались параллельно. Или в .NET предусмотренны какие-то свои методы работы с такими ситуациями.
Я вот читал Event-based Asynchronous Pattern Overview и все остальные сопутствующие статьи но так и не понял - там это как-то не естественно , всё. Хотелось бы чтоб программист графического интерфейса ставил свой обработчик и не задумавался ни о чём.
Создаешь класс с событием, например OnDataReceived, при этом сбор данных происходит в отдельном потоке, как ты и говорил. Если подписаться на событие такого объекта, то при вспыхивании события, обработчик выполнится в контексте потока сбора данных, что приведёт к исключению в случае манипуляций с GUI. Поэтому нужно делать так:
Код:
Поток считывающий информацию просто зажигает событие, потом что должно произойти:
Либо поток подписанный на это событие останавливаеться, и выпоняеться обработчик,
Либо в другом потоке выполняеться обработчик, но потокобезопасный.
Какой подход правильнее?
Цитата:
...обработчик, но потокобезопасный
Обработчик, выполняющияся в другом потоке, и получающий доступ к данным потока, скажем так "родителя", не может быть потокобезопасным.
Вот несколько статей:
Asynchronous Method Execution Using Delegates
Using asynchronous method calls in C#
Была ещё одна хорошая статья, но не нашёл её :-(
PS: возможно несколько не по теме, но если уж коснулись асинхронной обработки.
PPS: Посмотри ещё в сторону ThreadPool.
Для такого случая можно использовать сообщения (messaging). Чтобы при обработке события, которое работает с объектами GUI, но сгенерировнного потоком обработки пакетов, не произошло переключения контекста (ведь фрейм стэка обработчика события принадлежит контексту потока обработки пакетов) на поток GUI и не возникла взаимная блокировка, используй монитор и критическую секцию (всё это находится в System.Threading).