2015-02-20 3 views
1

Я пытался выяснить проблему с фоновой загрузкой, которую я делаю при запуске. Приложение работает отлично, но когда оно закрыто, оно вечно вечно. Я предположил, что это проблема с потоками. Я сузил его до следующего кода. Я гулял по всему миру, но не сталкивался с чем-либо, что соответствует той проблеме, которую я испытываю, может ли кто-нибудь подробно рассказать о безопасности потоков?C# WPF Background Loading Thread, Hang on Exit

Я предположил, что, учитывая, что экран загрузки закрыт, когда рабочий завершен (m_LoaderWindow.Close();), что это не будет проблематичным.

Этот код не работает

  m_LoaderWindow = new LoadingWindow(); 

      m_BackgroundWorker = new BackgroundWorker(); 
      OnProgressDelegate = m_BackgroundWorker.ReportProgress; 
      m_BackgroundWorker.WorkerReportsProgress = true; 
      m_BackgroundWorker.ProgressChanged += (object sender, ProgressChangedEventArgs arg) => 
      { 
       LoaderWindow.Context.Progress = arg.ProgressPercentage; 
      }; 

      m_BackgroundWorker.DoWork += MBackgroundWorkerOnDoWork; 
      m_BackgroundWorker.RunWorkerCompleted += MBackgroundWorkerOnRunWorkerCompleted; 
      m_BackgroundWorker.RunWorkerAsync(); 

      m_LoaderWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; 
      m_LoaderWindow.Owner = Application.Current.MainWindow; 
      m_LoaderWindow.ShowDialog(); 

Этот код работает (но, очевидно, не экран загрузки)

  m_BackgroundWorker = new BackgroundWorker(); 
      OnProgressDelegate = m_BackgroundWorker.ReportProgress; 
      m_BackgroundWorker.WorkerReportsProgress = true; 
      m_BackgroundWorker.ProgressChanged += (object sender, ProgressChangedEventArgs arg) => 
      { 
       LoaderWindow.Context.Progress = arg.ProgressPercentage; 
      }; 

      m_BackgroundWorker.DoWork += MBackgroundWorkerOnDoWork; 
      m_BackgroundWorker.RunWorkerCompleted += MBackgroundWorkerOnRunWorkerCompleted; 
      m_BackgroundWorker.RunWorkerAsync(); 

Вот рабочий завершил код

private void MBackgroundWorkerOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) 
    { 
     Application.Current.Dispatcher.Invoke(new Action(() => 
     { 
      m_LoaderWindow.Close(); 
     })); 
    } 
+2

FYI, событие RunWorkerCompleted будет срабатывать по потоку пользовательского интерфейса. Поэтому вам не нужно использовать Dispatcher.Invoke, чтобы закрыть окно вашего загрузчика. – RogerN

+0

Спасибо, ты прав. К сожалению, до сих пор не решена проблема :( – Asheh

ответ

1

Хорошо это WASN 't связан с чем-либо с резьбой. В моей модели ViewModel я делал это:

public LoadingWindow m_LoaderWindow = new LoadingWindow();

А потом я выделял его СНОВА в основной теме.

Хотя я не могу объяснить, почему это заставляет его висеть на выходе?

+2

Просто заработал это сам день или два назад. Создание нового окна в WPF, даже если вы его никогда не показываете, будет препятствовать отключению Диспетчера, если в окне нет было закрыто. Каждое появившееся окно должно иметь '.Close()', вызываемое на нем (явно или неявно через действие пользователя, например, щелчок по X в углу). –

+0

Один из тех ошибок, с которыми вам нужно сражаться :) спасибо ! – Asheh