以下是我所尝试的 - 它的工作原理,只要看到用户界面刷新,但我不认为它是最佳使用异步/等待。我该如何改进?在处理时更新WPF UI - 最佳使用异步等待
private async void btnQuickTest_Click(object sender, RoutedEventArgs e)
{
XmlReader reader;
int rowCount = 0;
using (reader = XmlReader.Create("someXmlFile.xml"))
{
while (reader.Read())
{
rowCount++;
DoSomeProcessingOnTheUIThread(reader);
//only update UI every 100 loops
if (rowCount > 0 && rowCount % 100 == 0)
{
//yay! release the UI thread
await Task.Run(() =>
{
Application.Current.Dispatcher.Invoke(
() =>
{
txtRowCount.Text = string.Format("{0}", rowCount);
});
});
}
} //end-while
}//end-using
}
什么是更好的方法?
UPDATE: 我避免基于克莱门斯的答案Dispatcher.Invoke,通过发送处理后台任务,并直接对UI更新进度。 我的代码现在看起来像。
private async void btnQuickTest_Click(object sender, RoutedEventArgs e)
{
XmlReader reader;
int rowCount = 0;
using (reader = XmlReader.Create("someXmlFile.xml"))
{
while (reader.Read())
{
rowCount++;
await DoSomeProcessing(reader);
//only update UI every 100 loops
if (rowCount % 100 == 0)
{
txtRowCount.Text = string.Format("{0}", rowCount);
}
} //end-while
}//end-using
MessageBox.Show("I am done!");
}
private Task DoSomeProcessing(XmlReader reader)
{
Task t =Task.Run(() =>
{
//Do my processing here.
});
return t;
}
更新#2: 在反思,为什么我在每个循环创建一个新的任务? 在一个后台任务中运行整个循环可能会更好。并定期提出回调以显示进度;见下面我的其他答案。
如果您的代码正常工作,但您希望某人提出改进建议,您可能需要在代码复审中提出此问题。 –
不应该在非UI线程上进行“一些处理”? – Fredrik
DoSomeProcessingOnTheUIThread做什么? – Fredrik