Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.04.2017, 19:24   #1
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию BackgroundWorker и две формы - C#

Имеется родительская форма, в который выполняется расчет (некоторый метод) в процессе которого данные передаются в дочернюю форму для динамической отрисовки. Это все работает. Захотел я чтобы главная форма не зависала в момент расчета. Поставил компонент BackgroundWorker, который и вызывает тот самый метод для вычислений. Теперь родительская форма не зависает, но зависает дочерняя, ее невозможно не свернуть ни закрыть даже после окончания расчета, хотя отрисовка работает по прежнему правильно, т.е. когда расчет идет отрисовка происходит, расчет заканчивается отрисовка тоже останавливается, только вот эта форма дочерняя так и остается заблокированной, а потом почему то сама закрывается. Как быть, может есть идеи?
PANDA8 вне форума Ответить с цитированием
Старый 11.04.2017, 09:26   #2
hoolygan
Пользователь
 
Регистрация: 11.04.2017
Сообщений: 64
По умолчанию

А зачем таким извратом заниматься?
Делай проще, есть 2 способа
1. Если под Фреймворк до 4.5 = через интерфейс IASyncResult + callback
2. Если на 4.5 и выше - то расчет проделывай через аsync/аwait, и вызывай вторую формочку через ShowDialog() и DialogResult
hoolygan вне форума Ответить с цитированием
Старый 12.04.2017, 16:15   #3
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию

Ну вот сделал через аsync/аwait. В итоге все работает также как с BackgroundWorker. А если вызывать не Show второй формы а ShowDialog то форма конечно не висит, но на ней ничего и не рисуется
PANDA8 вне форума Ответить с цитированием
Старый 12.04.2017, 16:30   #4
hoolygan
Пользователь
 
Регистрация: 11.04.2017
Сообщений: 64
По умолчанию

Давайте конткретнее задачу. UI это 1 поток, все расчеты делайте в асинхронном режиме. т.е. все рисовалки вызывайте в том же потоке, что и интерфейс, а математику во вторичном. Иначе мы друг друга не поймем. Можно, конечно же, высверлить недосягаемость UI потока, но это костыль, и не рекомендуется.
hoolygan вне форума Ответить с цитированием
Старый 12.04.2017, 16:42   #5
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию

Вот как код выглядит сейчас (лишнее я убрал, оставил только суть, чтобы Вы поняли)


PHP код:
private async Task Calculation() { 
            
Init();

            
await Task.Run(() => {

                
//вывод скоростей графическом виде
                
if (cbGraphics.Checked) {
                    
grForm = new GraphicsForm(XY);
                    
grForm.Show();
               
                }

               
double t 0;
               
//основной расчет
               
do {

                   
+= tau;   
 
                   
//расчет, в процессе которого значения в массивах Ux, Uy меняются  
                   
pu.Calculation(pressureCalcMethodnavierStokesCalcMethod
                                     
turbulenceModel);
                
 
                    
//вывод результатов в графическом виде
                    
if (cbGraphics.Checked) {
                       
grForm.DrawDisplay(UxUy);
            
                    }
                
                } while (
<= tmax);

           })

 }

private  
async void btnCalculate_Click(object senderEventArgs e) {
     
await Calculation();

PANDA8 вне форума Ответить с цитированием
Старый 12.04.2017, 16:50   #6
hoolygan
Пользователь
 
Регистрация: 11.04.2017
Сообщений: 64
По умолчанию

Ну вот и архитектурная ошибка огромнейшая. НЕЛЬЗЯ!!! в не-UI потоке работать с UI-потоком напрямую. Это грубейшее нарушение. Вы запускаете таску, она переходит в пул потоков, где и приступает к работе, когда до нее доходит очередь. Если так критично отрисовывать - то в таске просто меняйте переменные (например статические - они едины для потоков). А в главном потоке зарегистрируйте событие на изменение переменных и поставьте какой-то обработчик события на изменение этих переменных - и в обработчике рисуйте на здоровье.
hoolygan вне форума Ответить с цитированием
Старый 12.04.2017, 16:54   #7
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию

Спасибо, в принципе обдумывал такой вариант, но думал что можно найти выход из моей реализации...
PANDA8 вне форума Ответить с цитированием
Старый 12.04.2017, 16:56   #8
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию

Получается в принципе могу оставить и BackgroundWorker, т.к. там уже прогресс бар есть и отмена. Но просто от-туда извлечь отрисовку и поставить ее на событие? так?
PANDA8 вне форума Ответить с цитированием
Старый 12.04.2017, 16:59   #9
hoolygan
Пользователь
 
Регистрация: 11.04.2017
Сообщений: 64
По умолчанию

Можете и так, просто BackgroundWorker - это уже устаревшее на сегодняшний день решение. Как точно оно работает внутри - я не смотрел, если честно. Раньше вообще извращались через Application.DoEvents().
hoolygan вне форума Ответить с цитированием
Старый 12.04.2017, 18:41   #10
PANDA8
Пользователь
 
Регистрация: 28.03.2011
Сообщений: 38
По умолчанию

А не подскажете еще как в событии отслеживать изменение переменных?
PANDA8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Две формы в Delphi Kotlyar562 Помощь студентам 10 05.03.2011 23:36
Две формы. Перекрывание. Alex Cones Общие вопросы Delphi 4 30.05.2010 14:33
Вопрос про две формы... doniyor Общие вопросы Delphi 5 13.08.2009 17:18
две формы StakanpORTvejna Общие вопросы Delphi 4 04.05.2009 19:32
две формы в одном приложении.. AXEnic Общие вопросы Delphi 6 22.04.2009 16:52