Войти

Показать полную графическую версию : [решено] Проблемы обработки события, генерируемого другим потоком


Barit
08-02-2012, 14:57
надо:
из формы Form1 запустить поток, который через промежутки времени меняет контролы Form1.

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

Ничего не понимаю. Что искать, как бороться?

LilLoco
08-02-2012, 15:01
Barit, поясните, что значит
меняет контролы Form1 »
Приведите код, какая ошибка....

Barit
08-02-2012, 15:06
Ошибка:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
Additional information: Cross-thread operation not valid: Control 'button_read_information' accessed from a thread other than the thread it was created on.

здается, не может получить доступа к контролу Form1.

но обработчик события запускается из Form1. Целенаправленно создавал его, чтоб уйти от этой ошибки.

LilLoco
08-02-2012, 15:18
Barit, Объясните конкретнее что вы хотите сделать.
обработчик события запускается »
Какого события?

Прикрепите свой проект

Barit
08-02-2012, 15:34
надеюсь нужного не выбросил, выжимка в прилагаемом текстовом файле

LilLoco
08-02-2012, 15:45
Ну, судя по кускам кода, вы пытаетесь получить доступ к контролам "напрямую" из другого потока, что не правильно.

Почитайте про синхронизацию потоков.
Тут (http://forum.oszone.net/post-1471932.html#post1471932) есть один из вариантов доступа к контролам из потока. Думаю, разберетесь.

Barit
08-02-2012, 16:13
что ошибка из - за доступа к контролам из другого потока, понятно. Поэтому хочу замутить генерацию события из вторичного потока с обработкой в основном, чтобы избежать этой ошибки. Возможно ли сделать, чтобы обработчик был из основного потока?

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

Delirium
09-02-2012, 00:54
Как временное решение проблемы, ЧТО НЕ ПРАВИЛЬНО с точки зрения безопасности программ, можешь написать перед изменением
Control.CheckForIllegalCrossThreadCalls = false;
В таком случае исключение вызываться не будет при попытке доступа к контролам через другой поток.
Если же все делать правильно, то только через Invoke.

Пример, как я это реализовывал:

delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
private void SetControlPropertyValue(Control oControl, string propName, object propValue)
{
if(oControl.InvokeRequired)
{
SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
oControl.Invoke(d, new object[] { oControl, propName, propValue });
}
else
{
Type t = oControl.GetType();
PropertyInfo[] props = t.GetProperties();
foreach(PropertyInfo p in props)
{
if(p.Name.ToUpper() == propName.ToUpper())
{
p.SetValue(oControl, propValue, null);
}
}
}
}

Это функция, которую я вызываю при изменении из другого потока данных. Вызов довольно прост:

SetControlPropertyValue(GroupResultPanel, "Visible", true);
Параметры:
1. Имя контрола
2. Имя свойства
3. Значение.

Barit
09-02-2012, 09:54
модератор изменил название темы, исказив суть, прошу заменить на название типа:
"С# проблемы обработки события генерируемого другим потоком"
и удалить это сообщение (либо сам удалю).

Delirium
09-02-2012, 13:41
прошу заменить на название типа: »
надо:
из формы Form1 запустить поток, который через промежутки времени меняет контролы Form1. »
Почему же искажена суть. То, что выдается сообщение об ошибке, является следствием неверного управления поведением программы для доступа из другого потока.Но, раз уж так хочется, изменю.




© OSzone.net 2001-2012