it-roy-ru.com

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

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

delegate void lostfocs(string st);
   private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {

        Thread t = new Thread(modi);
        t.Start();
    }
 void modi()
    {
        try
        {
            label1.Content = "df";
        }
        catch
        {
            lostfocs ld = new lostfocs(up);
          //  ld.Invoke("df");
            object obj=new object();
            ld.Invoke("sdaf");
        }
    }
void up(string st)
    {
        label1.Content = st;
    }
22
Yasser

Используйте Dispatcher.Invoke Метод. 

Выполняет указанный делегат синхронно в потоке Диспетчер связан с.

Также

В WPF доступ может получить только поток, создавший DispatcherObject этот объект. Например, фоновый поток , который выделен из основной поток пользовательского интерфейса не может обновить содержимое кнопки, которая была создан в потоке пользовательского интерфейса. Для фоновой темы на Чтобы получить доступ к свойству Content кнопки, фоновый поток должен делегировать работу диспетчеру, связанному с потоком пользовательского интерфейса . Это достигается с помощью Invoke или BeginInvoke. Invoke is синхронный и BeginInvoke является асинхронным. Операция добавлена ​​в очередь событий Dispatcher с указанным DispatcherPriority.

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

Ознакомьтесь с этой статьей Потоки WPF создают более гибкие приложения с помощью Dispatcher

40
Habib

Вы можете использовать Диспетчер для этого. Ваш код становится ...

private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
    {
        try
        {
            label1.Content = "df";
        }
        catch
        {
            lostfocs ld = new lostfocs(up);
          //  ld.Invoke("df");
            object obj=new object();
            ld.Invoke("sdaf");
        }
    }
));
17
gaurawerma

использовать Диспетчер. Вызов

Пример

    void modi()
    {
        if(!Dispatcher.CheckAccess())
        {
            Dispatcher.Invoke(
                    ()=>label1.Content = "df",DispatcherPriority.Normal);
        }
        else
        {
            label1.Content = "df";
        }
    }
11
Tilak

Я запустил один не-пользовательский поток, и в этом потоке я тоже смотрел один пользовательский интерфейс. Таким образом, мое требование похоже на запуск потока пользовательского интерфейса в потоке без пользовательского интерфейса. При обработке этого сценария я получил следующее исключение . «Исключение: вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку».

В этом случае я использовал метод Dispatcher.Invoke элемента UI следующим образом, и он работал хорошо.

if (m_contextWindow == null)
{   
    System.Threading.Thread newWindowThread = new System.Threading.Thread(new ThreadStart( () =>
    {
        // Create and show the Window
        m_contextWindow = new ContextWindow();
        m_contextWindow.DataContext = this;                            
        m_contextWindow.Show();
        // Start the Dispatcher Processing
        System.Windows.Threading.Dispatcher.Run();
    }));

    // Set the apartment state
    newWindowThread.SetApartmentState(ApartmentState.STA);
    // Make the thread a background thread
    newWindowThread.IsBackground = true;
    // Start the thread
    newWindowThread.Start();
}
else
{                     
    this.m_contextWindow.Dispatcher.Invoke(new ThreadStart(() => 
    {
        m_contextWindow.DataContext = this;
        if (m_contextWindow.Visibility == System.Windows.Visibility.Collapsed
         || m_contextWindow.Visibility == System.Windows.Visibility.Hidden)
            m_contextWindow.Visibility = System.Windows.Visibility.Visible;
    }));                            
}
1
Srikanth Dornala

Несколько предложений по использованию BeginInvoke, но без упоминания EndInvoke. Хорошей практикой является то, что «каждый BeginInvoke имеет соответствующий EndInvoke» и, безусловно, должна быть некоторая защита от условий гонки (подумайте: что происходит с несколькими BeginInvoke кода, но ни один из них еще не завершил обработку?)

Это легко забыть, и я видел эту ошибку (и, да, это есть ошибка) как в примерах MSDN, так и в опубликованных книгах по WinForms

0
brewmanz
private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
            {
                try
                {
                    label1.Content = "df";
                }
                catch
                {
                    lostfocs ld = new lostfocs(up);
                    object obj = new object();
                    ld.Invoke("sdaf");
                }
            }));
        }
0
Kishore Kumar