2010-03-27 6 views
2

Предположим, что GUI (C#, WinForms) выполняет работу и занят в течение нескольких секунд. Он будет иметь кнопки, которые должны оставаться доступными, этикетки, которые будут меняться, прогресс бары и т.д.Лучшая практика для управления занятым графическим интерфейсом

Я использую этот подход в настоящее время, чтобы изменить графический интерфейс пользователя, когда занято:

//Generic delegates 
private delegate void SetControlValue<T>(T newValue); 

//... 
public void SetStatusLabelMessage(string message) 
{ 
    if (StatusLabel.InvokeRequired) 
     StatusLabel.BeginInvoke(new SetControlValue<string>(SetStatusLabelMessage, object[] { message }); 
    else 
     StatusLabel.Text = message; 
} 

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

ответ

6

Другой вариант - использовать BackgroundWorker и использовать ReportProgress, когда вам необходимо обновить графический интерфейс. Это обработает Invoke для вас, чтобы вам не пришлось беспокоиться об этом.

+0

У меня есть трудное время для согласования BackgroundWorkers и других потоков, используемых в программе. Как хорошо путешествующий джентльмен-программист, который вы видите чаще? Контроль через BackgroundWorker или Invoke? – MPelletier

+0

@MPelletier: BackgroundWorker для такого рода задач - у вас есть долго работающая задача, вам нужно, чтобы GUI был несовместим, и вам нужно показать индикатор выполнения. Это именно то, для чего был создан BackgroundWorker. –

+0

Я взял вопрос, чтобы быть более «лучшей практикой для обновления пользовательского интерфейса из фонового потока». Этот ответ действительно не затрагивает этот вопрос. –

1

Это выглядит правильно. Пока вы инкапсулируете подобные вещи в свой собственный проверенный класс, с ним не должно быть никаких проблем.

+0

К «в своем классе», вы имеете в виду, в отличие от класса формы? Я не для того, чтобы набирать максимум кода в классе формы, совсем наоборот, но если он * контролирует * форму, у меня есть привычка хранить ее * в классе формы. – MPelletier

+1

@MPelletier: Я имел в виду сохранить этот код, специфичный для пользовательского интерфейса, в стороне от приложения и бизнес-логики, которые уже должны были быть отделены от собственного класса. Итак, на самом деле, положить этот материал в класс формы отлично. – 2010-03-27 23:18:16

2

Лучшей практикой здесь является использование BackgroundWorker для запуска долговременной задачи. Это специальный класс потоковой передачи, специально созданный для WinForms, только для этой цели. Вы можете отправить ему работу, отменить ее, а также позволить ей отправлять сообщения обратно в поток WinForm для обновления статуса. В основном, используя BackgroundWorker, ваш графический интерфейс остается свободным и активным.

+0

Но он уже делает именно это, хотя и с другим классом, чем «BackgroundWorker». –

+1

Он попросил «передовой опыт». BackgroundWorker - «лучшая практика». –

2

Другие упомянули использование BackgroundWorker для запуска вашей работы. Это то, что вы делаете?

В любом случае, если вам интересно, какой лучший способ обновить пользовательский интерфейс из вашего фонового потока, то, что вы делаете, выглядит хорошо, хотя я рекомендую использовать Invoke вместо BeginInvoke. Кроме того, вместо того, чтобы объявить свой собственный отдельный делегат, вы можете использовать MethodInvoker, чтобы упростить код:

StatusLabel.Invoke(new MethodInvoker(delegate() { /* Update control here */ })); 
+0

Не использовать BackgroundWorker, no. В случае, когда BGW просто вызовет единственную линейную функцию, я бы это сделал, но я не решаюсь в какой-то программе, где фоновая функция использует ThreadPool. На этом уровне я чувствую, что я несущественную структуру. Спасибо за Invoke/BeginInvoke, который мне нужно обновить, чтобы лучше понять разницу. MethodInvoker тоже выглядит отлично! – MPelletier

+0

Нет проблем. Помогает ли это ответить на ваш вопрос, или есть что-то еще, что вы искали? –

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