我有一个工作线程,它在用户进行每次更改后为DataGrid计算数据。在某些情况下,用户更改得太快,所以在GUI线程上我调用
Thread.Abort();
与此同时,在工人线程上,我使用这样一个构造
while (true)
{
try
{
_calculateEvent.WaitOne();
...
Application.Current.MainWindow.Dispatcher.BeginInvoke((Action)delegate()
{
_viewModel.UpdateInterfaceFromAssigningInfo(assigningInfo);
});
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
}
我不知道它是否能工作,但目前我的主要问题是我不能调用GUI线程上的代码来更新界面。在Invoke
行,我有异常:InvalidOperationException
带有消息
调用线程无法访问此对象,因为线程拥有它。
我通常使用稍微不同的方式:
Application.Current.MainWindow.Dispatcher.BeginInvoke(new Action( ()=>
{
_viewModel.UpdateInterfaceFromAssigningInfo(assigningInfo);
}));
试试看,也许这是一个原因。
经过一些研究,我发现了准确满足我需求的信息,因为在我的情况下,只有在Task中的所有计算完成后,我才需要更新UI。
选项1。对于WPF应用程序,我们可以从同步上下文任务调度程序中受益,它在GUI线程上运行任务。所以,可以在任务完成后使用这样的场景来更新GUI:
Task t = Task.Run(() => foo());
t.ContinueWith((task) =>
{
// Update observable properties
}, TaskScheduler.FromCurrentSynchronizationContext());
继续任务将在GUI线程上执行,因此可以更新GUI。
选项2
private async void DownloadFileButton_Click(object sender, EventArgs e)
{
// Since we asynchronously wait, the UI thread is not blocked by our code.
await foo();
// Since we resume on the UI context, we can directly access UI elements.
UpdateObservableProperties();
}