Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток. WPF
Всякий раз, когда я обновляю ярлык, я получил эту ошибку: Вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток. Я пытался вызвать, но это не удалось. Я использую форму 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;
}
Ответы
Ответ 1
Использовать метод Dispatcher.Invoke.
Выполняет указанный делегат синхронно в потоке Диспетчер связан с.
Кроме
В WPF доступен только поток, создавший объект DispatcherObject этот объект. Например, фоновый поток, который выделяется из основной поток пользовательского интерфейса не может обновлять содержимое кнопки, которая была созданный в потоке пользовательского интерфейса. Для того чтобы фоновый поток доступ к свойству Content Button, фоновый поток должен делегировать работу диспетчеру, связанному с потоком пользовательского интерфейса. Это достигается с помощью Invoke или BeginInvoke. Вызов синхронный, а BeginInvoke - асинхронный. Операция добавляется к очередь событий Диспетчера в указанном DispatcherPriority.
Вы получаете ошибку, потому что ваш ярлык создан в потоке пользовательского интерфейса, и вы пытаетесь изменить его содержимое через другой поток. Здесь вам потребуется Dispatcher.Invoke.
Ознакомьтесь с этой статьей
WPF Threads создают более адаптивные приложения с Диспетчером
Ответ 2
Для этого можно использовать диспетчер. Ваш код будет...
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");
}
}
));
Ответ 3
использовать Dispatcher.Invoke
Пример
void modi()
{
if(!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(
()=>label1.Content = "df",DispatcherPriority.Normal);
}
else
{
label1.Content = "df";
}
}
Ответ 4
Я начал один поток, не связанный с UI, и в этом потоке я тоже смотрел один поток пользовательского интерфейса. Поэтому мое требование подобно запуску потока пользовательского интерфейса в потоке, отличном от UI. При обработке этого сценария я получил следующее исключение.
"Исключение: вызывающий поток не может получить доступ к этому объекту, потому что ему принадлежит другой поток.
В этом случае я использовал метод Dispatcher.Invoke элемента пользовательского интерфейса следующим образом, и он работал хорошо.
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;
}));
}
Ответ 5
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");
}
}));
}
Ответ 6
Несколько советов по использованию BeginInvoke, но не упоминание EndInvoke. Хорошая практика заключается в том, что "у каждого BeginInvoke есть соответствующий EndInvoke" и, конечно же, должна быть какая-то защита от условий гонки (подумайте: что происходит с несколькими BeginInvoke кода, но никто еще не завершил обработку?)
Легко забыть, и я видел эту ошибку (и, да, это ошибка) как в примерах MSDN, так и в опубликованных книгах по WinForms