C #: Могу ли я свернуть приложение в BackgroundWorker, работающее и обновить пользовательский интерфейс - PullRequest
0 голосов
/ 13 марта 2012

У меня запущен поток backgroundWorker.В конце я обновляю пользовательский интерфейс, минимизирую приложение и меняю значок.

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

Не может ли пользовательский интерфейс обновляться, когда приложение свернуто?Если можно, где я могу пойти не так.

ОБНОВЛЕНО:

@ Даниэль, Да, я в курсе.И когда задача выполнена, я вызываю ProgressChanged, и, наконец, также вызывается RunWorkerCompleted.НО, когда я минимизирую приложение посередине, компоненты, такие как Label, не меняются.Текст кнопки изменяется, но он зависает / застревает - кнопка больше не работает.Моя точка зрения такова: если приложение было свернуто во время выполнения DoWork, то когда вызывается ProgresChanged & RunCompleted или нет.Если вызывается, то почему определенные компоненты не изменены.ПРИМЕЧАНИЕ: если я не сверну в середине, то все будет отлично работать.

Ответы [ 2 ]

2 голосов
/ 13 марта 2012

Вы можете обновить пользовательский интерфейс только из потока пользовательского интерфейса.События ProgressChanged и RunWorkerCompleted выполняются в потоке пользовательского интерфейса, а событие DoWork - нет.Это означает, что если вы хотите обновить свой пользовательский интерфейс с BackgroundWorker во время его работы, вам нужно сделать это в обработчике события ProgressChanged.

1 голос
/ 13 марта 2012

Используете ли вы WPF или Winforms?В любом случае, если вы хотите что-то сделать с пользовательским интерфейсом, вам придется вернуться в поток пользовательского интерфейса.

Для этого в WPF вы можете использовать объект диспетчера и вызывать его, чтобы метод выполнялся потоком пользовательского интерфейса, а не вашим рабочим потоком.В Winforms вам придется поддерживать ссылку на некоторый элемент управления пользовательского интерфейса и вызывать этот элемент управления.

Рассмотрим следующий фрагмент кода (WPF):

    if (!myCheckBox.Dispatcher.CheckAccess())
{
  myCheckBox.Dispatcher.Invoke(
    System.Windows.Threading.DispatcherPriority.Normal,
    new Action(
      delegate()
      {
        myCheckBox.IsChecked = true;
      }
  ));
}
else
{
  myCheckBox.IsChecked = true;
}

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

Friend Shared Sub RaiseUiEvent(ByVal hnd As EventHandler, ByVal sender As Object, ByVal e As EventArgs)
    Dim uiRef = GlobalManager.GetInstance().UI

    Try
        uiRef.BeginInvoke(hnd, sender, e)

    Catch ex As InvalidOperationException
        ''if UiRef is null, then we simply drop the event
        Logger.AddTextToLog(ex)
        Debug.WriteLine("Invalid operation in raiseUiEvent")
    Catch ex As NullReferenceException
        Logger.AddTextToLog(ex)
        Debug.WriteLine("Null Reference in RaiseUiEvents")
    End Try
End Sub
...