我有很长的搜索操作,会定期更新 UI(发现事件 -> 更新 UI)
我尝试了很多方法来实现它:
异步/等待
public void PushButton() { await AsyncSearchAll(); } public async Task AsyncSearchAll(SearchPanelViewModel searchPanelViewModel, SearchSettings searchSettings, CancellationToken cancellationToken) { await Task.Factory.StartNew(() => { //searching for occurence //write it into panel }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); }
后台 worker
我想使用它,但我不想只使用 .ReportProgress() 访问 UI
调用
Dispatcher.BeginInvoke(()=>{//updating UI}) 的简单后台线程
/// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow { public MainWindow() { InitializeComponent(); } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { var backgroundThread = new Thread(CountToTen) { IsBackground = true }; backgroundThread.Start(); } private void CountToTen() { for (int i = 1; i <= 10000; i++) { var j = i; Dispatcher.BeginInvoke(new Action(() => Seconds.Text = j.ToString(CultureInfo.InvariantCulture))); } }
所有方法在完成线程后写入所有数据。 有什么方法可以运行后台任务来定期更新 UI 而不会通过阻止 ui 减慢程序速度?
最佳答案
最好将“工作人员”逻辑与“UI 更新”逻辑分开。
像这样:
public async Task AsyncSearchAll(SearchPanelViewModel searchPanelViewModel, SearchSettings searchSettings, CancellationToken cancellationToken)
{
while (..)
{
var results = await Task.Run(() => /* search more */);
/* update panel with results */
}
}
但是如果你想要实际的进度更新,也有办法做到这一点:
public async void PushButton()
{
Progress<MyUpdateType> progress = new Progress<MyUpdateType>(update =>
{
/* update panel */
});
await Task.Run(() => SearchAll(..., progress));
}
public void SearchAll(SearchPanelViewModel searchPanelViewModel,
SearchSettings searchSettings, CancellationToken cancellationToken,
IProgress<MyUpdateType> progress)
{
while (..)
{
/* search more */
if (progress != null)
progress.Report(new MyUpdateType(...));
}
}
关于c# - 长后台进程刷新 ui wpf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15699079/