2015-08-07 2 views
0

Я пытаюсь создать приложение для обновления для приложения wpf. У меня есть кнопка «Обновить» и маленький круглый загрузчик. После нажатия кнопки обновления появится загрузчик. Код обновления использует другой поток. Но когда я пытаюсь запустить другой процесс (Process.Start (path)) из потока обновлений, я получил exeption (вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток).не может начать другой процесс из потока C#

private void CheckUpdateButton_OnClick(object sender, RoutedEventArgs e) 
{ 
    VisibleLoadingForCheckUpdate = true; 
    var myThread = new Thread(CheckNeedUpdateApplication); 
    myThread.Start(); 
    myThread.Name = "UpdateThread"; 
    IsEnabled = false; 
} 

private void CheckNeedUpdateApplication() 
{ 
    if (_baseWindow.ProgramWorked) 
    { 
     return; 
    } 

    try 
    { 
     var myDelegate = new Action(LoaderStop); 
     if (NeedUpdate()) 
     { 
      MessageBoxResult updateDecision = 
       MessageBox.Show(@"Install update?", 
        @"Update", MessageBoxButton.YesNo); 
      if (updateDecision == MessageBoxResult.Yes) 
       InstallUpdate(); 
      Dispatcher.Invoke(myDelegate); 
     } 
     else 
     { 
      MessageBox.Show(@"No update found", @"Update", MessageBoxButton.OK, MessageBoxImage.Information); 
      Dispatcher.Invoke(myDelegate); 
     } 
    } 
    catch (Exception) 
    { 
     MessageBox.Show(this, @"Connection error", 
      @"Error", MessageBoxButton.OK, MessageBoxImage.Error); 
     var myDelegate = new Action(LoaderStop); 
     Dispatcher.Invoke(myDelegate); 
     //throw new Exception("Error"); 
    } 
} 

void LoaderStop() 
{ 
    VisibleLoadingForCheckUpdate = false; 
    IsEnabled = true; 
} 

private void InstallUpdate() 
{ 
    try 
    { 
     var newApp = _updateServiceApiClient.GetProgramArchive(_baseWindow.ProgramIdentity); 
     if (newApp.IsSuccess) 
     { 
      using (var decompress = ZipFile.Read(new MemoryStream(newApp.Result))) 
      { 
       decompress.ExtractAll(Application.StartupPath + Path.DirectorySeparatorChar + "update", ExtractExistingFileAction.OverwriteSilently); 
      } 
      try 
      { 
       var pInfo = new ProcessStartInfo(UpdaterFilePath) {UseShellExecute = false}; 
       var mProcess = new Process {StartInfo = pInfo}; 
       mProcess.Start(); //EXCEPTION 
       _baseWindow.Close(); 
       Close(); 
      } 
      catch 
      { 
       MessageBox.Show(this, @"Update Error.", 
            @"Error", MessageBoxButton.OK, MessageBoxImage.Error); 
       LoggerHelper.ErrorsLogger("Update error."); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(this, @"Update Error", 
      @"Error", MessageBoxButton.OK, MessageBoxImage.Error); 
     //throw new Exception("Ошибка при обновлении."); 
    } 
} 

Как я могу запустить другое приложение из другого потока?

+0

В WPF поток WPF может получить доступ к объектам пользовательского интерфейса. http://stackoverflow.com/questions/11625208/accessing-ui-main-thread-safely-in-wpf http://stackoverflow.com/questions/1775843/how-to-directly-access-the -ui-thread-from-the-backgroundworker-thread-in-wpf – user2184057

+0

Какая строка кода генерирует исключение? –

+0

@GlenThomas, var pInfo = new ProcessStartInfo (UpdaterFilePath) {UseShellExecute = false}; var mProcess = new Process {StartInfo = pInfo}; mProcess.Start(); // ИСКЛЮЧЕНИЕ в методе InstallUpdate() –

ответ

0

вы не можете обновить интерфейс из другого потока, так как пользовательский интерфейс работает на MainThread. Вы используете MessageBox.Show(), который должен отображаться в пользовательском интерфейсе. Кроме того, вы не можете возвращать значения элементов управления пользовательского интерфейса, когда на другом потоке. В этом случае используйте диспетчер для обновления пользовательского интерфейса и чтения информации с элементов управления пользовательского интерфейса.

+0

Есть ли способ вызвать process.Start (pathToExe) в другом потоке, а не в MainThread. В этот момент я получил исключение –

+0

Проблема не в том, что вы создаете поток из MainThread. Проблема в том, что вы используете некоторые элементы пользовательского интерфейса внутри нового потока процессов. Пример MessageBox. и что такое _baseWindow? – Akansha

+0

Я думаю, проблема в InstallUpdate(). Вы можете видеть messageBox? И что такое _baseWindow? – Akansha

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