2012-09-12 3 views
0

Обычная практика - показать окно выполнения (с индикатором выполнения) в потоке пользовательского интерфейса и обновить прогресс от рабочего потока.Отображение Progressbar: наоборот

У меня много длинных операций, которые запускаются и запускаются в самой графической оболочке (что временно блокирует графический интерфейс). Требование состоит в том, чтобы показать индикатор выполнения всех существующих длительных операций. Обычным решением было бы перемещать длинные операции как потоки и обновлять прогресс оттуда. Но я не уверен в безопасности потоков этих длительных операций.

Есть ли способ показать окно прогресса в другом потоке (так что оно не замерзает), а затем обновить прогресс от самого основного потока графического интерфейса?

+0

Я бы предположить, что было бы лучше в долгосрочной перспективе для вас реорганизовать затянувшийся код из UI и в отдельные классы, которые могут выполняться в другом потоке. Это сэкономит вам много горя и поможет вам написать лучший код в будущем. – Enigmativity

+0

Я бы тоже хотел это сделать. Но эти операции были написаны кем-то еще в прошлом с участием файлов, базы данных, элементов управления пользовательского интерфейса и всех восприимчивых небезопасных вещей. Время и усилия не способствуют нарушению статус-кво. – Socrates

+0

Я был бы склонен к разному, но я уверен, что у вас было бы лучшее представление о сложности, чем я. Я бы подумал, что вы бросаете хорошее время для разработчиков после плохого и просто ухудшаете ситуацию. Обучение рефактору сложных систем - это навык, с которым вы лучше справляетесь с практикой. – Enigmativity

ответ

1

Я не знаю, как показать ProgressBar в другом потоке, но взломать вы можете попробовать, чтобы система выполнила свои действия (обновить интерфейс) из ваших длительных операций. Для этого, вы можете вызвать следующую функцию несколько раз внутри ваших длительных операций:

public static void DoEvents() { 
    DispatcherFrame frame = new DispatcherFrame(); 
    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) { 
    frame.Continue = false; 
    return null; 
}), null); 
    Dispatcher.PushFrame(frame); 
} 

Но будьте осторожны, это не хороший способ решить эту проблему. Лучше выбрать подходящий дизайн.

1

Проверить это thread

Я думаю, вы должны использовать Application.DoEvents()

+0

Это winforms. OP отметил, что это вопрос, поскольку WPF и WPF не имеют Application.DoEvents. Вот почему я опубликовал функцию замены. Но, как уже упоминалось: это всего лишь обходной путь. – HCL

+0

Использование 'Application.DoEvents()' чрезвычайно плохой практики и может вызывать всевозможные проблемы с такими вещами, как повторное подключение. – Enigmativity

+0

mmhmm, так что нам делать, если мы хотим переместить индикатор выполнения в пользовательском интерфейсе с помощью потока? кстати, я извиняюсь за свой ответ, я думал, что это winform :) – spajce

Смежные вопросы