Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Общие вопросы по .NET и C# > С# Многопоточность |
Автор: bobr 6.4.2008, 22:00 |
Друзья, пишу текстовый редактор, хочется, чтобы в программе было несколько потоков. 1-ый поток - основной. 2-ой поток отслеживает позицию курсора (номер линии, на которой курсор находится) и выводит эту текущую позицию в некоторый textBox. Пишу 2-ой поток таким образом: public class ThreadClass { public void Execute() { while (true) { textBox1.Text = richTextBox1.SelectionStart+" "; Thread.Sleep(100); } } } а мне выдаются ошибки вида: Error 7 Cannot access a nonstatic member of outer type 'TeEd.TeEdForm' via nested type 'TeEd.TeEdForm.ThreadClass' E:\Documents and Settings\1\Рабочий стол\textEd1\TeEd\TeEdForm.cs 69 24 TeEd Error 8 Cannot access a nonstatic member of outer type 'TeEd.TeEdForm' via nested type 'TeEd.TeEdForm.ThreadClass' E:\Documents and Settings\1\Рабочий стол\textEd1\TeEd\TeEdForm.cs 69 40 TeEd помогите разобраться, в чем дело. (если можно, напишите кусочек кода) Заранее спасибо. |
Автор: marcusmae 6.4.2008, 22:10 | ||
bobr, до кусочка работающего кода, боюсь, сразу дело не дойдёт, поскольку ошибка состоит в том, что нестатические (то есть, экземплярные) поля textBox1 и richTextBox1, которые компилятор квалифицирует как относящиеся к outer (то есть, внешнему по отношению к ThreadClass) типу TeEd.TeEdForm, не могут быть употреблены в nested (то есть, вложенном) типе ThreadClass. Упрощая, та же самая ошибка содержится в следующем фрагменте :
|
Автор: bobr 7.4.2008, 00:06 |
Друзья, если есть возможность, объясните в общих чертах, как справиться с такой задачей. есть поле richTextBox, в нем пишут текст, нужно, чтобы параллельно с этим основным потоком работал другой, определяющий в какой строчке находится курсор, и выводящий эту информацию в какой-нибудь textBox. marcusmae, спасибо за помощь, сделал эти классы "равнозначными", т.е. вынес один из другого, но прога не работает - выдается ошибка. Заранее всем спасибо. |
Автор: bobr 8.4.2008, 02:12 |
marcusmae, большое спасибо!!! (читаю много литературы по Шарпу, но там в основном потоки рассмотрены на консольных примерах, здесь как раз проблем нет, у меня же проблема во взаимодействии классов...) основная моя проблема, в том, как из класса, образующего второй поток обратиться к объекту (textBox) основного класса. (понимаю, что вопрос дилетантский, но в C# делаю пока еще только первые шаги) Если вам не трудно, напишите маленький пример такого вида: дана простая форма с двумя textbox: tb1 и tb2. и есть второй поток, который читает информацию из tb1 и записывает ее в tb2. (на этом примере, думаю,у меня получится разобраться как класс потоков взаимодействует с объектами основного класса) |
Автор: marcusmae 8.4.2008, 19:50 | ||||||||||||||||||
Нормальный вопрос! Чтобы экземпляр объекта был доступен, он должен быть либо членом класса, либо переданным извне параметром в скобочках. Последнее, думаю, сразу понятно, а стать членом класса необходимый объект может либо в результате соответствующего наследования :
- все публичные (public) и защищённые (protected) элементы RichTextBox теперь есть и у ManagedRichTextBox, либо явно, по Вашему желанию :
Видно, что в предыдущем примере мне не пришлось никаким образом передавать textBox-ы в ManagedRichTextBox, потому что я создал их, во-первых, прямо в нём и, во-вторых, не на стороне основного потока, а на стороне вспомогательного :
Всё наоборот. Основная форма в начале своей жизни регистрируется на получение события о том, что вспомогательный поток сам создал textBox-ы :
- (см. в файле Form1.Designed.cs) После чего она стартует вспомогательный поток :
Если у вспомогательного потока всё получилось, то после создания textBox-ов он разошлёт уведомления всем слушателям события CursorsTextBoxesReady :
Среди слушателей обязательно окажется форма со своим обработчиком CursorTextBoxesReadyEventHandler, в котором подхватываются ссылки на textBox-ы и доопределяются всякие дизайнерские параметры. Всё это проделал всё тот же вспомогательный поток! Остаётся добавить textBox-ы на форму, чем, в силу устройства контролов, вспомогательный поток заниматься не может. Метод Invoke - это способ организации межпроцессорного взаимодействия между компонентами форм. При следующем вызове
процедура InitializeCursorManagment ставится на выполнение в очередь контрола this (то есть, самой формы), причём выполняется это не вспомогательным потоком, а тем, который создал форму, то есть основным. Одновременно с этим вспомогательный поток ведёт свои дела. Он устанавливает таймер, срабатывающий с заданным интервалом. Зарегестрированный на событие таймера Elapsed обработчик
вычисляет новые координаты курсора, опять же, через Invoke, поскольку обработчик сработал во вспомогательном потоке, но нужен Handle контрола ManagedRichTextBox, а ManagedRichTextBox создан основным потоком. Затем координаты сразу же попадают в textBox-ы. А с событием CursorsTextBoxesUpdated вышла оплошность. Вообще говоря, при нынешнем расположении, оно возникает раньше, чем обновляются координаты. Стоит поместить его после обновления координат textBox-ов. Но это не очень важно, поскольку оно не используется. Ну вот. Занимательный рассказ? ![]() |
Автор: marcusmae 8.4.2008, 20:15 | ||||||
Окей, предыдущий вариант, возможно, на первый взгляд витееват, но у него есть и преимущества. Для разнообразия, поменяем схему : пусть оба textBox-а создаются основным потоком, а вспомогательный только играется с будильником.
Этот LinkedTextBox - это TextBox, расширенный необходимой функциональностью. Здесь явно присутствует передаваемый параметр (к Вашему вопросу), имеющий косвенное отношение к обоим textBox-ам : parentThreadControl.
В данном варианте форма регистрируется на событие, связанное с обновлением textBox-ов и сама занимается их текстом. Что для этого нужно сделать на стороне вспомогательного потока? Во-первых, словить срабатывание таймера. А во-вторых, при сигнализации необходимости обновления textBox-ов переключиться в основной поток, чтобы созданные в нём textBox-ы могли быть изменены. В отличие от предыдущего, этот вариант неудобен возможными проблемами при закрытии формы. Действительно, что будет, если форма вместе со своими textBox-ами уже начала освобождать ресурсы, а вспомогательный поток, как ни в чём не бывало, отправит туда предложение обновиться? = Будет вывалено исключение о попытке обратиться к объекту, который уже уничтожается (parentThreadControl, он же - экземпляр формы) ![]() http://ipicture.ru/Gallery/Viewfull/1264759.html |
Автор: Alexandr507 22.2.2010, 18:31 | ||
В продолжении темы о потоках в windows form Разрабатываю приложение в котором нужен второй поток, создал статический метод подскажите как туда передать всю форму попробовал что то типа этого, не получается
|
Автор: KelTron 22.2.2010, 18:41 | ||
Только учти, что ничего хорошего не выйдет, если ты будешь пытаться из этого потока обращатсья к гую. http://msdn.microsoft.com/en-us/library/ms171728.aspx |