在我的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。
请给我宝贵的建议。
答案 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"));
}