c# - 长后台进程刷新 ui wpf

标签 c# wpf multithreading async-await

我有很长的搜索操作,会定期更新 UI(发现事件 -> 更新 UI)

我尝试了很多方法来实现它:

  1. 异步/等待

    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());
    }
    
  2. 后台 worker

    我想使用它,但我不想只使用 .ReportProgress() 访问 UI

  3. 调用 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/

相关文章:

c# - 插件中的 ASP .NET Core MVC 2.1 mvc View

c# - 如何查明当前登录的用户是否在该域中?

c# - 带有javascript确认功能的必填字段验证器未验证

c# - 满足要求的接口(interface)或抽象类

wpf - 为什么人们在 XAML 样式元素中指定 BasedOn ="{x:Null}"?

php - 并发访问MySQL数据库

带有 ListBox 的 WPF ListBox - UI 虚拟化和滚动

c# - 使 WPF TextBox 绑定(bind)触发每个新角色?

linux - OSX 上的应用程序不能生成超过 2048 个线程

java - Java 日历操作的结果不一致