Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

События (Типа Delphi)

723
11 сентября 2006 года
Tommy
78 / / 13.10.2002
Короче такое дело. Я пишу программу которая принимает пакеты из сети, и значит у неё есть графический интерфейс. Хтелось бы что б был некоторый объект отвечающий за отправку и получение данных, и у него были события которые он зажигает по приходу некоторых пакетов, а графический интерфейс реагирует а них, только вот пакеты слушаються в одном потоке, а графический интерфейс работает в другом. И когда зажигаеться событие, надо чтобы все происходило как в Delphi - то есть прерывался поток, выполнялся(лись) обработчики событий и т.д..
Вопрос: Воббще правильно ли это, или нужно чтоб события обрабатывались параллельно. Или в .NET предусмотренны какие-то свои методы работы с такими ситуациями.
Я вот читал Event-based Asynchronous Pattern Overview и все остальные сопутствующие статьи но так и не понял - там это как-то не естественно , всё. Хотелось бы чтоб программист графического интерфейса ставил свой обработчик и не задумавался ни о чём.
713
12 сентября 2006 года
Ap0k
360 / / 13.03.2006
Тут все довольно просто. Может на первый взгляд всё покажется насколько мутным :-)
Создаешь класс с событием, например OnDataReceived, при этом сбор данных происходит в отдельном потоке, как ты и говорил. Если подписаться на событие такого объекта, то при вспыхивании события, обработчик выполнится в контексте потока сбора данных, что приведёт к исключению в случае манипуляций с GUI. Поэтому нужно делать так:
Код:
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
    {
        //тут уже можно делать любые манипуляции с интерфейсом и данными
        //правда ещё нужно задумываться над потокобезопасностью данного кода
    }
}
723
13 сентября 2006 года
Tommy
78 / / 13.10.2002
Мне кажеться что выполнение в потоке сбора информации недопустимо, т.к. он положим может пропустить получение каких либо данных, или что будет если считывание происходит асинхронно? Ну и вообще я думал так:
Поток считывающий информацию просто зажигает событие, потом что должно произойти:
Либо поток подписанный на это событие останавливаеться, и выпоняеться обработчик,
Либо в другом потоке выполняеться обработчик, но потокобезопасный.

Какой подход правильнее?
713
14 сентября 2006 года
Ap0k
360 / / 13.03.2006
Чтобы не останавливался поток сбора информации, необходимо использовать BeginInvoke вместо Invoke. Тогда в контексте потока сбора выполнится лишь вызов метода (BeginInvoke) а сбор продолжится, не дожидаясь выполнения кода, т.е. как раз и получится, что событие зажглось, а всё то, что будет происходить дальше не интересует поток сбора. Это имеет смысл в WinForms, когда необходимо обработать данные в интерфейсном потоке и отобразить их пользователю. В случае если сама обработка данных занимает непозоволительно много времени, нужно и её выполнять в отдельном потоке. Так что подход необходомо выбирать исходя из конкретной задачи.
Цитата:
...обработчик, но потокобезопасный


Обработчик, выполняющияся в другом потоке, и получающий доступ к данным потока, скажем так "родителя", не может быть потокобезопасным.

Вот несколько статей:
Asynchronous Method Execution Using Delegates
Using asynchronous method calls in C#
Была ещё одна хорошая статья, но не нашёл её :-(
PS: возможно несколько не по теме, но если уж коснулись асинхронной обработки.
PPS: Посмотри ещё в сторону ThreadPool.

273
14 сентября 2006 года
3A3-968M
1.2K / / 22.12.2005
Для такого случая можно использовать сообщения (messaging). Чтобы при обработке события, которое работает с объектами GUI, но сгенерировнного потоком обработки пакетов, не произошло переключения контекста (ведь фрейм стэка обработчика события принадлежит контексту потока обработки пакетов) на поток GUI и не возникла взаимная блокировка, используй монитор и критическую секцию (всё это находится в System.Threading).
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог