每当我刷新一个标签,我得到这个错误: 因为不同的线程拥有它调用线程不能访问该对象。 我试图调用但它的失败。 我使用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;
}
使用Dispatcher.Invoke方法。
同步执行的Dispatcher关联的线程上执行指定的委托。
也
在WPF中,只有线程创建DispatcherObject可以访问该对象。 例如,从主UI线程派生的后台线程不能更新在该UI线程上创建的按钮的内容 。 为了让后台线程能够访问Button的Content属性,后台线程必须与委托UI线程相关的工作给调度。 这是通过使用Invoke或BeginInvoke来完成。 调用是同步的而BeginInvoke是异步的。 该操作被添加到分派器的事件队列中在指定的DispatcherPriority。
你所得到的错误,因为是在UI线程创建的标签,你试图通过修改另一个线程的内容。 在这里,您将需要Dispatcher.Invoke。
看看这篇文章WPF线程构建更加适应应用与调度
您可以使用调度此。 你的代码变得...
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");
}
}
));
使用Dispatcher.Invoke
例
void modi()
{
if(!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(
()=>label1.Content = "df",DispatcherPriority.Normal);
}
else
{
label1.Content = "df";
}
}
我开始一个非UI线程并且此线程内我盯着一个UI线程太多。 所以,我的要求是像非UI线程中运行的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;
}));
}
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");
}
}));
}
几点建议使用的BeginInvoke,但没有提到EndInvoke会的。 良好的做法是,“每一个的BeginInvoke有一个匹配的EndInvoke会”,当然需要有对抗的比赛条件有所保障(个人认为:与多个代码的BeginInvoke会发生什么,但没有完成处理了吗?)
人们很容易忘记,我已经看到了这个错误(是的,这是错误的),在这两个例子MSDN和WinForms的书籍出版
文章来源: The calling thread cannot access this object because a different thread owns it.WPF