【发布时间】:2016-06-10 22:55:24
【问题描述】:
这是我想做的简化版本:
onClick button,aNewMethod() 将异步运行以保持 UI 响应。就是这样!
我已经阅读了一些答案,这就是我能想到的:
private async void button_Click(object sender, RoutedEventArgs e)
{
Task task = Task.Run(() => aNewMethod());
await task;
}
private void aNewMethod()
{
if (progress.Value == 0)
{
//Heavy work
for (int i = 1; i < 1000000000; i++) { }
progress.Value = 100;
}
}
您可能已经想到,这会在if(progress.Value== 0) 处抛出一个System.InvalidOperationException 说:
调用线程无法访问该对象,因为不同的 线程拥有它。
在谷歌搜索后,我了解到我需要一个 Dispatcher.BeginInvoke() 方法来更新/使用 UI 控件,所以我这样做了:
private void aNewMethod()
{
Dispatcher.BeginInvoke((Action)delegate {
if (progress.Value == 0)
{
//Heavy work
for (int i = 1; i < 1000000000; i++) { }
progress.Value = 100;
}
});
}
这解决了System.InvalidOperationException,但它没有异步运行,因为 UI 仍然冻结在for loop
所以问题是:如何异步运行aNewMethod(); 并且仍然更新并与 UI 控件交互?
【问题讨论】:
-
使用
Dispatcher.InvokeAsync -
Sakura:我觉得这和 Dispatcher.BeginInvoke 差不多,见stackoverflow.com/questions/13412670/…
-
您正试图在另一个线程中访问 UI 线程对象,而该线程对象并非是 allwoed
-
您明确要求
Sleep在 UI 线程上运行。不知道你还能期待什么。
标签: c# wpf asynchronous task dispatcher