многопоточность: новая форма закрывается слишком быстро

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

Я вызываю новую тему, создаю свою форму, но как только она появляется, форма закрывается...

Вот мой код из моего основного:

    frmProgress f = new frmProgress();
    Thread t = new Thread(new ThreadStart(delegate() { f.Show(); }));
    t.Start();
    documentManager.Compile(); //This is my big action
    t.Abort();

Вот код формы:

    public frmProgress()
    {
        InitializeComponent();
    }

Я хотел бы знать, что я сделал неправильно.

Спасибо!


person LolCat    schedule 25.07.2012    source источник
comment
Вы смотрели на класс BackgroundWorker и его метод ReportProgress?   -  person Dan    schedule 25.07.2012
comment
Да, но я подумал, что будет проще использовать new Thread() и прервать, когда я закончу...   -  person LolCat    schedule 25.07.2012
comment
@LolCat Нет, на самом деле все гораздо проще.   -  person Servy    schedule 25.07.2012
comment
@LolCat Возможно, стоит создать простое тестовое приложение и использовать примеры, указанные в ответе Серви. Как только я познакомился с BackgroundWorker, он во много раз облегчил мне жизнь.   -  person Dan    schedule 25.07.2012
comment
Тогда попробую с BackgroundWorker. Спасибо вам обоим.   -  person LolCat    schedule 25.07.2012


Ответы (1)


У вас есть несколько проблем:

  1. Вы показываете форму в потоке, отличном от пользовательского интерфейса. Это вызовет только проблемы; это должно быть в потоке пользовательского интерфейса.
  2. Вы выполняете длительную задачу в потоке пользовательского интерфейса; это блокирует обновления пользовательского интерфейса.

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

Отличным инструментом для работы здесь является использование файла BackgroundWorker. Он сделает большую часть работы за вас, чтобы убедиться, что правильный код работает в потоках пользовательского интерфейса/не пользовательского интерфейса, как это должно быть. Создайте новый BackgroundWorker и поместите длительную задачу в событие DoWork. Сделайте любые простые обновления пользовательского интерфейса, которые вам нужны (показывая форму), прежде чем запускать BGW, и выполните любую очистку в событии Completed (которое будет выполняться в пользовательском интерфейсе). На странице MSDN на BackgroundWorker есть несколько хорошие примеры.

Еще одно преимущество использования BackgroundWorker заключается в том, что вы можете легко сообщать о прогрессе (если у вас есть хороший способ узнать свой % завершения), а не просто иметь полосу выделения. Просто добавьте обработчик к обработчику событий ProgressReported для обновления индикатора выполнения и периодически вызывайте метод ReportProgress при выполнении работы. Точные фрагменты кода см. в связанных примерах.

person Servy    schedule 25.07.2012