Gui зависает при использовании потоков - PullRequest
5 голосов
/ 04 марта 2011

Я застрял и надеялся, что кто-нибудь сможет мне помочь.

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

В одном из моих классов графического интерфейса в конструкторе в первой строке я делаю новый экземпляр этого класса и затем выполняю

    LoadingBar bar = new LoadingBar();
    Thread thread = new Thread(bar.Show);
    thread.Start();

Однако даже основной поток программыПродолжая делать более интенсивные вещи, этот графический интерфейс по-прежнему зависает, даже если я использую backround worker.

Что-то не так с подходом, который я упомянул, и если да, что мне нужно изменить?

Спасибо

Ответы [ 4 ]

6 голосов
/ 04 марта 2011

Вы должны поменять свой метод. Графический интерфейс должен оставаться в главном потоке, пока работа выполняется в «рабочем потоке» (обычно BackGroundWorker). Затем работник отправляет отчет в графический интерфейс, который затем обновляется.

2 голосов
/ 04 марта 2011

Тебе лучше поступить наоборот.Сделайте интенсивную работу в потоке (или в фоновом режиме) и покажите экран ожидания в главном потоке приложений.

1 голос
/ 04 марта 2011

Вам нужно использовать BackgroundWorker. Перетащите его на форму, нажмите backgroundWorker1 и установите для свойства WorkerReportsProgress значение True

.

Затем перейдите к событиям (через окно свойств) и прикрепите обработчики для

  • DoWork, это где вся работа, которая представлена ​​индикатором выполнения. Через это вы будете «сообщать о прогрессе», и фоновый работник будет следить за тем, чтобы ProgressChanged вызывался в потоке пользовательского интерфейса.
  • ProgressChanged, здесь вы обновляете пользовательский интерфейс на основе данных о ходе и состоянии, переданных методу

DoWork событие выглядит примерно так

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    var userState = new StateClass();

    while (working)
    {
        // TODO: do work here

        // update the state surrounding this task via userState
        userState.property = "some status";

        // report the progress so that backgroundWorker1_ProgressChanged gets called 
        this.backgroundWorker1.ReportProgress(percentComplete, userState);
    }

}

ProgressChanged событие выглядит так

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // e.UserState contains the state data you passed to ReportProgress, 
    //   you have to cast it to the right type though, since its of type object
    var userState = (StateClass)e.UserState;
    int progress = e.ProgressPercentage;

    // TODO: report progress to the UI with the above variables
}

Теперь все, что вам нужно сделать, это попросить фонового работника сделать работу, позвонив this.backgroundWorker1.RunWorkerAsync()

0 голосов
/ 04 марта 2011

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

РЕДАКТИРОВАТЬ

Добавить вызов к System.Threading.Thread.Sleep(1);после вашего отчета о прогрессе звоните

...