powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / окно ожидания
25 сообщений из 32, страница 1 из 2
окно ожидания
    #38320118
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ситуация простая: нужно вызвать диалоговое окно, пока что-то выполянется в другом потоке. Причем сделать это так, чтобы было очень удобно использовать. С backgroundWorker что-то решения мне не понравились, но нашел вот такой способ:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
using (SplashWindow ....("load data...") //открывает форму, где просто надпись
			{
				var task = new Task(() =>
					{
						for (int i = 0; i < 1000; i++)
						{
							res = Math.Sin(45.6);
							Thread.Sleep(50);
						}
					});

				var nestedFrame = new DispatcherFrame();
				task.ContinueWith(_ => nestedFrame.Continue = false);
				task.Start();
				Dispatcher.PushFrame(nestedFrame);
				task.Wait();
				task.Dispose();

				MessageBox.Show(res.ToString(CultureInfo.InvariantCulture));
			}


Если честно напрягает использование Dispatcher.PushFrame, могут тут быть подводные камни? Спасибо за подсказку)
...
Рейтинг: 0 / 0
окно ожидания
    #38320291
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanЕсли честно напрягает использование Dispatcher.PushFrame, могут тут быть подводные камни? Спасибо за подсказку)Идея использовать Task - правильная. У меня была раньше реализация через PushFrame, не понравилась. В итоге понравилась такая постановка задачи:
Код: c#
1.
2.
3.
4.
5.
6.
    Task.Factory
        .StartNew(() => { ... })
        .ContinueWith(() => { ... })
        .ContinueWith(() => { ... })
        .LockUi(); // <= Расширяющий метод для Task.
        .ContinueWith(() => { ... })


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    public static class UiTaskHelper
    {
        public static Task<T> LockUi<T>(this Task<T> task)
        {
            return UiExecutionLocker.I.SetTask(task); // о ужас, синглетон :-) 
        }

        public static Task LockUi(this Task task)
        {
            return UiExecutionLocker.I.SetTask(task);
        }
    }


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    public class UiExecutionLocker
    {
        public Task<T> SetTask<T>(Task<T> task)
        {
            AddRef(); // инкремент счётчика ссылок + отображение диалога
                          // форма отображается через BeginInvoke + ShowDialog.
            return task.ContinueWithSync(t =>
            {
                Release(); // декремент счётчика ссылок + закрытие диалога
                return t.Result;
            });
        }

        public Task SetTask(Task task)
        {
            AddRef();
            return task.ContinueWithSync(t =>
            {
                Release();
                t.ThrowIfException();
            });
        }
    }
...
Рейтинг: 0 / 0
окно ожидания
    #38320375
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

не поверишь, именно от тебя ждал ответа. Чем не понравился frame? Можешь пример использования вашего велосипеда скинутЬ?
...
Рейтинг: 0 / 0
окно ожидания
    #38320409
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanне поверишь, именно от тебя ждал ответа.Неожиданно. :-)
netivanЧем не понравился frame?Я наверное по другому сформулирую. Через frame решение вполне рабочее, но с предлагаемым решением работать удобнее , если асинхронности базируются на тасках. Боюсь, я точно сейчас не смогу сформулировать недостатки. Нужно вспоминать, писать примеры. :-)

Тут вообще возможны два способа индикации выполняемой фоновой задачи:
1. Обсуждаемый случай - диалогом. Применяется, если нужно блокировать UI на время выполнения фоновой операции.
2. Индикация без блокирования UI. Можно сделать какой-нибудь анимацией в статусбаре главной формы, или ещё как.

Одно из преимуществ - для обоих случаев применяется одинаковый подход.
netivanМожешь пример использования вашего велосипеда скинутЬ?Первый фрагмент кода и есть пример использования. Если там что-то непонятно - уточните вопрос, я поясню.
...
Рейтинг: 0 / 0
окно ожидания
    #38320416
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё желательно сделать отображение диалога с задержкой (где-то в 0.5 секунды), чтобы для коротких тасков диалог не мелькал на экране. Но это уже следующий шаг. :-)
...
Рейтинг: 0 / 0
окно ожидания
    #38320419
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, гавнокод. Нужно декларативно через mvvm.
...
Рейтинг: 0 / 0
окно ожидания
    #38320426
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно и так сформулировать - при использовании тасков в PushFrame нет необходимости. :-)
...
Рейтинг: 0 / 0
окно ожидания
    #38320434
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУгавнокод.Ну можно же подобрать другое слово. У нас же вроде мараторий на фекальные формулировки. :-)
МСУНужно декларативно через mvvm.Конечно. Но это уже следующий этап. Аспнетчикам не понять.
...
Рейтинг: 0 / 0
окно ожидания
    #38320441
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНу можно же подобрать другое слово.
Ок. "кодкоторыйнихеранекоррелируетскачествомиэргономикой" :)

Алексей ККонечно.
Всё должно само замлиться и декларативно подтягиваться :)
...
Рейтинг: 0 / 0
окно ожидания
    #38320445
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

можно про AddRef и Release подробнее.
...
Рейтинг: 0 / 0
окно ожидания
    #38320452
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей К, можно про AddRef и Release подробнее.
Ну а что тут подробнее, утечка на утечке и утечкой погоняет
...
Рейтинг: 0 / 0
окно ожидания
    #38320463
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей К,

можно про AddRef и Release подробнее.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        RefCounter IsActiveRefCounter = new RefCounter(); 
            
        void AddRef() 
        {   
            if (IsActiveRefCounter.IsNoReference) 
            { 
                  // показываем диалог, только асинхронно, через Dispatcher.BeginInvoke
            } 
  
            IsActiveRefCounter.AddRef(); 
        } 
  
        void Release() 
        {  
            IsActiveRefCounter.Release(); 
  
            if (IsActiveRefCounter.IsNoReference) 
            { 
                 // закрываем диалог
            } 
        }


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    public class RefCounter 
    { 
        int Count; 
  
        public void AddRef() 
        { 
            Count++; 
        } 
  
        public void Release() 
        { 
            if (IsNoReference) 
                throw new InvalidOperationException("IsNoReference == true"); 
  
            Count--; 
        } 
  
        public bool IsNoReference 
        { 
            get { return Count == 0; } 
        } 
    } 
...
Рейтинг: 0 / 0
окно ожидания
    #38320467
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУnetivanАлексей К, можно про AddRef и Release подробнее.
Ну а что тут подробнее, утечка на утечке и утечкой погоняет Тебя SeVa что ли укусил?
...
Рейтинг: 0 / 0
окно ожидания
    #38320472
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей К,

можно про AddRef и Release подробнее.Это надо на случай, когда одновременно выполняются несколько тасков. Мы же не будем для них показывать несколько диалогов "Подождите". :-)
...
Рейтинг: 0 / 0
окно ожидания
    #38320482
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КnetivanАлексей К,

можно про AddRef и Release подробнее.Это надо на случай, когда одновременно выполняются несколько тасков. Мы же не будем для них показывать несколько диалогов "Подождите". :-) ага, только ща понял. Спасибо! Только у меня все же пока что 1 Таск планируется. Сейчас попробую с вашим примером)
...
Рейтинг: 0 / 0
окно ожидания
    #38320498
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К, сколько же опасного кода :)

Окно ожидания в вебе с блокировкой UI:

Код: javascript
1.
$.blockUI({ message: '<h4><img src="busy.gif" />Лячкайте... Выполняется что-то.</h4>' }); });



Делов-то .
...
Рейтинг: 0 / 0
окно ожидания
    #38320544
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей К, сколько же опасного кода :)

Окно ожидания в вебе с блокировкой UI:

Код: javascript
1.
$.blockUI({ message: '<h4><img src="busy.gif" />Лячкайте... Выполняется что-то.</h4>' }); });



Делов-то . Вообще-то мы обсуждаем реализацию. Прикладной код проще некуда. Давай я его ещё раз повторю, для верности. :-)
Код: c#
1.
2.
3.
4.
5.
    Task.Factory
        .StartNew(() => { ... })
        .ContinueWith(() => { ... })
        .ContinueWith(() => { ... })
        .LockUi(); // <= оно самое
...
Рейтинг: 0 / 0
окно ожидания
    #38320554
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей Кпропущено...
Это надо на случай, когда одновременно выполняются несколько тасков. Мы же не будем для них показывать несколько диалогов "Подождите". :-) ага, только ща понял. Спасибо! Только у меня все же пока что 1 Таск планируется. Сейчас попробую с вашим примером)Ещё обрати внимание на ContinueWithSync. Это ContinueWith через шедулер, привязанный к контексту синхронизации главного UI-потока.
...
Рейтинг: 0 / 0
окно ожидания
    #38320558
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВообще-то мы обсуждаем реализацию. Прикладной код проще некуда. Давай я его ещё раз повторю, для верности. :-)
Всё-равно, пока еще не знаю, но что-то мне не нравится в этом коде :)
...
Рейтинг: 0 / 0
окно ожидания
    #38320561
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУАлексей КВообще-то мы обсуждаем реализацию. Прикладной код проще некуда. Давай я его ещё раз повторю, для верности. :-)
Всё-равно, пока еще не знаю, но что-то мне не нравится в этом коде :)Не бесит, уже хорошо. :-)
...
Рейтинг: 0 / 0
окно ожидания
    #38320566
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КНе бесит, уже хорошо. :-)
Ну, не бесит, конечно, но суховато как-то... Десктоп он такой :)
...
Рейтинг: 0 / 0
окно ожидания
    #38320591
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КМСУпропущено...

Всё-равно, пока еще не знаю, но что-то мне не нравится в этом коде :)Не бесит, уже хорошо. :-)
ну так. Может еще обернуть в RunTaskAsynkWithMsgBox()
...
Рейтинг: 0 / 0
окно ожидания
    #38320621
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanАлексей Кпропущено...
Не бесит, уже хорошо. :-)
ну так. Может еще обернуть в RunTaskAsynkWithMsgBox()Мне в виде расширяющего метода для таска нравится больше. Тем более, после закрытия диалога "подождите" может быть продолжение, вроде:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    Task.Factory
        .StartNew(() => { ... })
        .ContinueWith(() => { return Task.Factory.FromAsync(...); })
        .Unwrap();
        .ContinueWith(() => { ... })
        .LockUi(); // подождите
        .ContinueWithSync(() => // про синхронизацию писал выше.
        {
              // окошко надо показать после закрытия диалога "подождите"
              MessageBox.Show("Тру ла ла");
        })
        .ContinueWith(() => { ... }) // ещё что-то асинхронное
        .LockUi(); // ещё раз подождите
        .ContinueWithSync(() =>
        {
              MessageBox.Show("Ну теперь точно готово");
        })
        .LogExceptions(); // запись ошибок в лог, к теме отношения не имеет, но добавил навсякий :-)
...
Рейтинг: 0 / 0
окно ожидания
    #38320639
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ужас ёпт
...
Рейтинг: 0 / 0
окно ожидания
    #38320658
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanну так. Может еще обернуть в RunTaskAsynkWithMsgBox()Ну и конечно же, .LockUi() отображает дефолтный диалог, описанный как синглетон. Если для таска нужен специальный диалог, то создаём UiExecutionLocker явно. Получается что-то вроде того, что ты предлагаешь:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var task = Task.Factory.StartNew(() => { ... });

var locker = new UiExecutionLocker
{
    Content = new MyUserControlOrЧтоТоЕщё() // содержимое окна
}; 

locker
    .SetTask(task)
    .ContinueWith(t => { ... }) // какое-то продолжение после закрытия окна, если надо
    .LogExceptions(); // не забываем обрабатывать ошибки. :-)
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / окно ожидания
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]