调用线程无法访问此对象

时间:2013-03-15 07:14:06

标签: c# wpf multithreading

在我的wpf应用程序中,我在按钮单击中添加了一段代码,如下所示:

 private void btn_convert_Click(object sender, RoutedEventArgs e)
 {
    Thread t = new Thread(new ThreadStart(WorkerMethod));
    t.SetApartmentState(ApartmentState.MTA);
    t.IsBackground = true;
    t.Start();
 }

在我的WorkerMethod()方法中,我有一些代码,如下面一行:

btn_convert.Content = "Convert";

当它到达此行时,它会抛出异常,因为调用线程无法访问此对象,因为另一个线程拥有它。

我不想使用Dispatcher,因为它会冻结UI .. UI应该是响应式的,所以我没有选择Dispatcher invoke或BeginInvoke。

请给我宝贵的建议。

2 个答案:

答案 0 :(得分:7)

  

我不想使用Dispatcher,因为它冻结了UI.UI应该是响应式的,所以我不选择Dispatcher invoke或BrginInvoke。

这只是表明您已经严重使用了调度员。

必须从UI线程访问UI。这并不意味着您的整个WorkerMethod需要在UI线程上运行,但这一行:

btn_convert.Content = "Convert";
确实如此。因此,您可能希望保留当前用于启动线程的代码(但是您确实需要设置公寓状态),但更改访问UI的任何代码以使用调度程序。例如:

Action setButtonContentAction = () => btn_convert.Content = "Convert";
Dispatcher.BeginInvoke(setButtonContentAction);

或者,根据您WorkerThread正在做的事情 - 如果您使用的是C#5 - 您可能想要使用新的异步功能。这可以使UI更容易在UI线程上工作,但它确实取决于正在发生的其他事情。

答案 1 :(得分:1)

UI更改只能由主线程应用。您可以检查是否需要主线程调用:

if (btn_convert.InvokeRequired)
{
  btn_convert.Invoke((MethodInvoker)(() => btn_convert.Content = "Convert"));
}