Отображение окна в отдельном потоке работает только один раз - PullRequest
0 голосов
/ 05 апреля 2019

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

private Thread tBusy;


private void ShowBusyWindow(string message, double top, double left, double height, double width)
{
    BusySplash busyForm = new BusySplash(message, top, left, height, width)
    busyForm.Show();
}

private void ShowBusy(string message, UIElement container)
{
    if (busy != null) return;

    double top = container.PointToScreen(new Point(0, 0)).Y;
    double left = container.PointToScreen(new Point(0, 0)).X;
    double width = container.RenderSize.Width;
    double height = container.RenderSize.Height;


    ThreadStart ts = new ThreadStart(() => ShowBusyWindow(message, top, left, height, width));
    tBusy = new Thread(ts);

    tBusy.SetApartmentState(ApartmentState.STA);
    tBusy.IsBackground = true;
    tBusy.Start();
}

private void HideBusy()
{

    tBusy.Abort();
    tBusy = null;
}

Я окружаю код, выполняя работу с функцией ShowBusy () в начале и HideBusy () в конце.

Но, к сожалению, ShowBusy () запускается один раз успешно, а затем выдает:

System.InvalidOperationException: 'Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку.'

Что я могу сделать, чтобы предотвратить эту ошибку? Я попытался выполнить busyForm.Show() с помощью диспетчера busyForm, но получил ту же ошибку.

1 Ответ

0 голосов
/ 05 апреля 2019

Работа пользовательского интерфейса должна быть выгружена в поток пользовательского интерфейса.

private void ShowBusyWindow(string message, double top, double left, double height, double width)
{
    Application.Current.Dispatcher.Invoke(() => {
        BusySplash busyForm = new BusySplash(message, top, left, height, width)
        busyForm.Show();
    });
}

Несколько вещей, хотя:

  • Вам действительно не нужно создавать отдельный поток STA для вашего индикатора занятости. Перенесите работу без пользовательского интерфейса в задачу, чтобы пользовательский интерфейс не блокировался. Оттуда, только сделать обновления пользовательского интерфейса в потоке пользовательского интерфейса. Похоже, причина, по которой ваш пользовательский интерфейс блокируется, заключается в том, что вы слишком много делаете для пользовательского интерфейса.
  • Отмена потока, чтобы закрыть индикатор занятости, немного странная. Гораздо понятнее просто позвонить. Закрыть на элементе управления (при условии, что это окно WPF).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...