以下是我所嘗試的 - 它的工作原理,只要看到用戶界面刷新,但我不認爲它是最佳使用異步/等待。我該如何改進?在處理時更新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