0

在我的 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 调用或 BeginInvoke。

请给我您宝贵的建议。

4

2 回答 2

7

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

这只是表明您对调度程序的使用不当。

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

btn_convert.Content = "Convert";

绝对可以。因此,您可能希望保留当前用于启动线程的代码(您是否真的需要设置单元状态),但更改任何访问 UI 的代码以使用调度程序。例如:

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

或者,根据您WorkerThread在做什么——以及如果您使用的是 C# 5——您可能想要使用新的异步功能。这可以使 UI 在 UI 线程上工作变得更容易,但这确实取决于其他情况。

于 2013-03-15T07:19:25.513 回答
1

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

if (btn_convert.InvokeRequired)
{
  btn_convert.Invoke((MethodInvoker)(() => btn_convert.Content = "Convert"));
}
于 2013-03-15T07:20:36.080 回答