powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / dispatcher.BeginInvoke ?
13 сообщений из 13, страница 1 из 1
dispatcher.BeginInvoke ?
    #38602446
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет.
Как можно из отдельного потока изменить текст у лейбла на форме - дождаться пока текст изменится (перерисуется, чтобы пользователь увидел изменение текста), а потом уже выполнять что-то ?


Думал подойдет такое решение:
Код: c#
1.
2.
3.
4.
5.
var waitOperation = dispatcher.BeginInvoke(new Action(() =>
                        {
                            myForm.lbl.Content = "Ожидайте";
                        }),DispatcherPriority.Send);
waitOperation.Wait();



Но нет. Надпись не меняется, а длительная операция начинает выполнятся.

Подскажите как решить пожалуйста.
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602714
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть идеи ?
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602749
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WPF Падаван,

что надо сделать - то? В ходе выполнения задачи в другом потоке на форму что-то передать?
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602764
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да простоту нужно сделать.

После нажатия на кнопку будет происходить 15 секундное действо. Хочу просто тупо в лейбл на форме вывести "выполняем операцию, ждите". После чего запустить длительную штуку.

Проблема всего лишь в том, что надпись в лейбле не перерисовывается, после того как я меняю Контент. Т.е. выполняется длительнаня операция и только когда она завершается, лейбл и меняется (хотя уже поздно).

PS. Я тут подумал, получается работа идет не в отдельном потоке, а в потоке Интерфейса.... Ну и фиг с ним.

В Дельфи, для этого, используется Application.ProcessMesages.

А вот в WPF не знаю. Думал, мой вариант пройдет. Я удивлен, что не сработало. Почему ? Вроде бы даю команду диспетчеру, жду завершения выполнения... А результата на экране не вижу.


Ну тогда подскажите другой вариант может ?
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602768
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Знаю, что у уважаемого "Алексей К " есть проект, где сделан отдельный прогресс бар для длительных операций. Но это не нужно сейчас мне.
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602856
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WPF ПадаванЗнаю, что у уважаемого "Алексей К " есть проект, где сделан отдельный прогресс бар для длительных операций. Но это не нужно сейчас мне.
если Net 4.5 async -await самое простое решение. Если нет, то:
//псевдокод
Код: c#
1.
2.
3.
Main Thread:
textBox.Text = "start ..."
Task.Start( ()=> do operation).ContinuiWith( t=>after task end . T.Result :... Textbox.text="End",TaskScheduler.FromCurrentSynchronizationContext()
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38602858
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38603171
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот эта вся сожность, только на замену простого метода Assplication.ProcessMessages ?
хм... ВПФ...
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38603205
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WPF ПадаванВот эта вся сожность, только на замену простого метода Assplication.ProcessMessages ?
хм... ВПФ...а в чем сложность? запускать в цикле Doevent это же полное УГ. Можете backgroundworker, если ностальгия мучает.
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38603324
Фотография @k@DElpher
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivanWPF ПадаванВот эта вся сожность, только на замену простого метода Assplication.ProcessMessages ?
хм... ВПФ...а в чем сложность? запускать в цикле Doevent это же полное УГ. Можете backgroundworker, если ностальгия мучает.
А я вот тут неожиданно очень захотел этот ProcessMessages. Попался чужой контрол. graphlight.codeplex.com Сам по себе хороший. Захотел в него ProgressBar воткнуть на время выполнения вычислений. (рисует графы, сложность там в позиционировании элементов).
В итоге алгоритмическая часть контрола работает со своей "ViewModel", которая в данный момент непосредственно прицеплена к XAML элементам. То есть алгоритм двигает вершины графа, вершины генерируют свои PropertyChanged вроде Top, Left. И всё это работает в одном потоке.
Запихать всё это в отдельный поток не получается - менять значения элементов управления нельзя, недопустимый межпотоковый.
Надо было, чтоб алгоритм в время работы менял только с модель, выдавал конечный результат, и только потом отдавал его во все ViewModel: например, просто скопировать весь DrawingGraph(это центральная модель и ViewModel контрола) с его внутренностями, обработать отдельно и вернуть результат в XAML. Но это долго и внимательно надо.
В итоге пришлось скостылить так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
              public abstract class BaseViewModel : INotifyPropertyChanged
...
  protected void RaisePropertyChanged(string name)
        {
            if (BaseViewModel.IsNotifyEnabled)   // Отключил уведомление, после обработки включил обратно. 
            {                                                    //Класс BaseViewModel - создан разработчиком контрола и там останется жить,                if (PropertyChanged != null)                          // не влияя на мои модельки
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }


То есть перед обработкой в фоне я отключаю для DrawingGraph возможность уведомлять XAML, после обработки включаю обратно, чтоб показывать результат.
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38603986
DoctorZelen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
WPF Падаван,

если не используете MVVM то можно так сделать

var loadData = new Thread(() =>
{
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => myForm.lbl.Content = "Ожидайте"));

тут длительные вычисления

Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => myForm.lbl.Content = "Загрузка завершена"));
}
}) {IsBackground = true};
loadData.Start();

как-то так
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38604892
WPF Падаван
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за помощь.
Ок. Будем считать это специфическими особенностями WPF.
...
Рейтинг: 0 / 0
dispatcher.BeginInvoke ?
    #38716368
Ростигай
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предлагаю такое решение.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
private SynchronizationContext SyncContext;
..
// в каком либо методе, конструкторе формы:
SyncContext = SynchronizationContext.Current;


....
// Обновляем компонент, и ЖДЕМ пока операция завершится
SyncContext.Send(_ => myLabel.Visibility = System.Windows.Visibility.Hidden, null);  
// Метод Send посылает синхронное сообщение.



Dispatcher.Invok почему-то не работает.
TaskScheduler.FromCurrentSynchronizationContext предназначен скорее для регулирования выполнения всей задачи (таска). Используется в различных продолжениях (continuation) и мало подходит, если нужно в середине асинхронного метода, быстренько, изменить один компонент формы. Хотя, если сделать цепочку, где одна задача будет делать вычисления, а последняя задача-продолжение, будет расчитанные данные разносить на форме, то TaskScheduler.FromCurrentSynchronizationContext будет выглядеть органичней, чем блок кода вызванный через SyncContext.Send/Post.

Жду критику. У меня работает, но может это частный случай просто.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / dispatcher.BeginInvoke ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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