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

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

Моя проблема:

У меня есть страница: PosterHome.xaml с равномерной сеткой. В моем коде программной части у меня есть поток:

drawThread = new Thread(new ThreadStart(drawPosters));
                drawThread.SetApartmentState(ApartmentState.STA);
                drawThread.Start();

Этот метод потока (drawPosters) иногда просыпается другим классом с помощью автозаполнения. Я получаю ошибку в этом методе в тот момент, когда меняю строки однородной сетки:

while (true)
{
  waitEvent.WaitOne();
  //do some calculations
  // change uniform grid rows & cols
  posterUniformGrid.Rows = calculatedRows; //**-> error is first thrown here**
  posterUniformGird.Columns = calculatedCols;             
}

Как мне с этим справиться? Заранее спасибо.

Приветствует Даана


person Daan    schedule 17.02.2012    source источник
comment
Какие сообщения на форуме вы просматривали и почему они не применимы к вашей ситуации? Вы искали сообщения о Диспетчере?   -  person mbeckish    schedule 17.02.2012
comment
Если вы ввели в Google точный заголовок своего вопроса, первое обращение дало вам глубокое объяснение того, что происходит.   -  person Clemens    schedule 17.02.2012
comment
Я действительно пробовал использовать диспетчер, но, видимо, я сделал что-то не так, потому что у меня это не сработало ... но я использовал пример, который дал Аарон, и он сработал!   -  person Daan    schedule 17.02.2012


Ответы (2)


Вы пытаетесь получить доступ к posterUniformGrid, который был создан в потоке пользовательского интерфейса из фонового потока.

Чтобы этого избежать, используйте Диспетчер.

Dispatcher.Invoke(DispatcherPriority.Normal, 
                    new Action<object[]>(SetGrid), 
                    new object[] { calculatedRows, calculatedColumns });
person Aaron McIver    schedule 17.02.2012
comment
+1. Ага: это даже более совместимо с WPF, чем мой старый ответ - person Mehdi LAMRANI; 17.02.2012

Вы можете попробовать это:

 while (true)
 {
   waitEvent.WaitOne();
   this.InvokeEx(t => t.posterUniformGrid.Rows = calculatedRows); 
   this.InvokeEx(t => t.posterUniformGird.Columns = calculatedCols);             
 }

 public static class ISynchronizeInvokeExtensions
    {
        public static void InvokeEx<T>(this T @this, Action<T> action) where T : ISynchronizeInvoke
        {
            if (@this.InvokeRequired)
            {
                try
                {
                    @this.Invoke(action, new object[] { @this });
                }
                catch { }
            }
            else
            {
                action(@this);
            }
        }
    }
person Mehdi LAMRANI    schedule 17.02.2012