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

Ваш аккаунт

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

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

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

serialPort ?

25K
26 февраля 2007 года
faradey
3 / / 26.02.2007
вот хочу маленькую программку написать с ком-портом, но наткнулся на след. грабли:

 
Код:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {//обработчик приема байт
            ...//проверки всякие
            this.button2_Click(this, null);// <--вот тут хочу вызвать ф-цию.
            //возвращается ошибка

        }


вот ее содержание:
Цитата:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll

Additional information: Cross-thread operation not valid: Control 'button2' accessed from a thread other than the thread it was created on.



заранее благодарен.

547
27 февраля 2007 года
Hydra
488 / / 20.06.2006
Похоже у тебя поток1 вызывает процедуру из потока2, а та в свою очередь опять процедуру из потока1.
Такие вещи синхронизировать надо.
273
27 февраля 2007 года
3A3-968M
1.2K / / 22.12.2005
Все проще, все наследники Control - это Single-thread объекты. Обращаться к элементам управления можно только из того потока, который создал этот элемент. Но можно выполнить cross-thread вызов. Для этого из другого потока вызываешь синхронизированный метод Invoke и передаёшь в него делегат. Этот делегат будет выполнен в одном потоке с элементом управления. Поэтому внутри обработчика serialPort1_DataReceived выполнение метода button1_Click должно быть таким:
 
Код:
[SIZE=2][FONT=Courier New]button1.Invoke([/FONT][/SIZE][FONT=Courier New][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]EventHandler[/COLOR][/SIZE][SIZE=2](button1_Click), [/SIZE][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#008080]EventArgs[/COLOR][/SIZE][SIZE=2]());[/SIZE][/FONT]

Т.е. происходит вызов synchronize-метода (т.е. он всегда синхронизирован и не может вызвать падение потока) Invoke у контрола button1, он принимает код, который будет выполнен в одном потоке с контролом. Далее передаю аргументы для вызова button1_Click - это источник сообщения и аргументы события.
25K
27 февраля 2007 года
faradey
3 / / 26.02.2007
Спасибо всем откликнувшимся. Я что-то подобное и думал, но сам бы не сделал...

Все заработало с вызовом:

 
Код:
button1.Invoke(new EventHandler(button1_Click), this, new EventArgs());
273
27 февраля 2007 года
3A3-968M
1.2K / / 22.12.2005
Цитата: faradey
Спасибо всем откликнувшимся. Я что-то подобное и думал, но сам бы не сделал...


Только учти, что подобный вызов останавливает поток, в котором опрашивается порт до окончания выполнения данного метода в UI-потоке. Для того, чтобы не ждать UI-поток (в случае, если код обработчика кнопки отнимает дополнительные ресурсы), используй button1.BeginInvoke.

25K
01 марта 2007 года
faradey
3 / / 26.02.2007
Цитата: 3A3-968M
Только учти, что подобный вызов останавливает поток, в котором опрашивается порт до окончания выполнения данного метода в UI-потоке. Для того, чтобы не ждать UI-поток (в случае, если код обработчика кнопки отнимает дополнительные ресурсы), используй button1.BeginInvoke.



спасиб. попробовал так, все работает хоть я и не заметил особой разницы :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог