Подтвердить что ты не робот

Диспетчер WPF { "вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток".}

Сначала мне нужно сказать, что я noob с WPF и С#. Приложение: Создайте изображение Мандельброта (GUI) Мой диспетчер отлично работает в этом случае:

  private void progressBarRefresh(){

       while ((con.Progress) < 99)
       {
           progressBar1.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate
                {
                    progressBar1.Value = con.Progress;
                }
              ));
       }
  }

Я получаю сообщение (заголовок), когда tring делает это с помощью приведенного ниже кода:

bmp = BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, stride);

this.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate
            {                     
                img.Source = bmp;
                ViewBox.Child = img;  //vllt am schluss
            }
          ));

Я попытаюсь объяснить, как работает моя программа. Я создал новую тему (потому что GUI не отвечает) для вычисления пикселей и цветов. В этой теме (методе) я использую диспетчер для обновления моего изображения в ViewBox после того, как вычисления будут готовы.

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

4b9b3361

Ответ 1

На всякий случай, если вы хотите, чтобы объект был разделен между разными потоками, всегда создавайте этот объект в потоке пользовательского интерфейса. Позже, когда вы хотите получить доступ к объекту, вы можете проверить, есть ли у вас доступ к объекту. Если у вас нет доступа, повторно вызовите функцию с доступом к потоку пользовательского интерфейса. пример кода ниже:

    private void YourMethod()
    {
        if (Application.Current.Dispatcher.CheckAccess())
        {
            // do whatever you want to do with shared object.
        }
        else
        {
            //Other wise re-invoke the method with UI thread access
            Application.Current.Dispatcher.Invoke(new System.Action(() => YourMethod()));
        }
    }

Ответ 3

Вы создаете растровое изображение (bmp) в потоке рабочего (?), а затем передаете его в поток пользовательского интерфейса - это не работает.

Вам нужно создать изображение в потоке пользовательского интерфейса. Вероятно, вам понадобится какой-то способ ссылки на изображение, которое вы хотите отобразить, и передать эту информацию в пользовательский интерфейс.

Ответ 4

Вы также можете использовать механизм массового обслуживания для передачи сообщений между потоками. В конце концов, это то, как работает архитектура Windows. Это то, что делает диспетчер. Вы передаете ссылку в делегат, который не принадлежит потоку WPF.

Итак, у вас есть основная идея, но вам нужно передать битмап в другой поток, используя Action<T>(T object) или в вашем случае:

Dispatcher.Invoke(DispatcherPriority.Send, new Action<Bitmap>(delegate(Bitmap img) {
    do things here...
}), bmp);

Ответ 5

Когда вы получаете Dispatcher, вы получаете разные для каждого потока.

this.Dispatcher может дать вам еще один диспетчер, а не пользовательский интерфейс, поэтому вы получите эту ошибку.

Попробуйте вместо этого использовать Application.Current.Dispatcher, это всегда будет возвращать диспетчер потока пользовательского интерфейса.

Такая же ошибка может произойти, если вы используете Dispatcher.CurrentDispatcher из другого потока, конечно.