c# – 从TPL任务向WPF视图报告进度的适当方法是什么?

c# – 从TPL任务向WPF视图报告进度的适当方法是什么?,第1张

概述我试图从小的“块”或页面中读取数据库中的大量行,并将进度报告给用户;即,如果我在加载每个块时加载100个“块”报告进度. 我在C#4.0中使用TPL从数据库中读取这些块,然后将完整的结果集交给另一个可以使用它的任务.我觉得TPL让我能更好地控制任务取消和切换,而不是BackgroundWorker等,但似乎没有一种内置的方式来报告任务的进度. 这是我实现的向WPF进度条报告进度的解决方案,我想确保 我试图从小的“块”或页面中读取数据库中的大量行,并将进度报告给用户;即,如果我在加载每个块时加载100个“块”报告进度.

我在C#4.0中使用TPL从数据库中读取这些块,然后将完整的结果集交给另一个可以使用它的任务.我觉得TPL让我能更好地控制任务取消和切换,而不是BackgrounDWorker等,但似乎没有一种内置的方式来报告任务的进度.

这是我实现的向WPF进度条报告进度的解决方案,我想确保这是合适的,并且我应该采取更好的方法.

我首先创建了一个简单的界面来表示不断变化的进度:

public interface INotifyProgressChanged{  int Maximum { get; set; }  int Progress { get; set; }  bool IsIndeterminate { get; set; }}

这些属性可以绑定到WPF视图中的Progressbar,并且接口由支持viewmodel实现,后者负责启动数据加载并最终报告整体进度(本示例简化):

public class Contactsviewmodel : INotifyProgressChanged{  private IContactRepository repository;  ...  private voID LoadContacts()  {    Task.Factory.StartNew(() => this.contactRepository.LoaDWithProgress(this))      .ContinueWith(o => this.UseResult(o));  }}

您会注意到我将viewmodel作为INotifyProgressChanged传递给存储库方法,这是我想确保我没有做错的地方.

我的思考过程是,为了报告进度,实际执行工作的方法(存储库方法)需要访问INotifyProgressChanged接口,以报告最终更新视图的进度.这里快速浏览一下存储库方法(本例简述):

public class ContactRepository : IContactRepository{  ...  public IEnumberable<Contact> LoaDWithProgress(INotifyProgressChanged indicator)  {    var resultSet = new List<Contact>();    var query = ... // This is a liNQ to EntitIEs query    // Set the maximum to the number of "pages" that will be iterated    indicator.Maximum = this.GetNumberOfPages(query.Count(),this.pageSize);    for (int i = 0; i < indicator.Maximum; i++)    {      resultSet.AddRange(query.Skip(i * this.pageSize).Take(this.pageSize));      indicator.Progress += 1; // As each "chunk" is loaded,progress is updated    }    // The complete List is returned after all "chunks" are loaded    return resultSet.AsReadonly();  }}

这就是存储库最终通过viewmodel向VIEw报告进度的方式.这是正确的方法吗?我是否正确使用TPL,违反任何主要规则等?这个解决方案正在运行,正在按预期报告进展情况,我只是想确保我没有为失败做好准备.

解决方法 执行此 *** 作的“规定”方法是将 TaskScheduler实例从 TaskSheduler::FromCurrentSynchronizationContext传递到 ContinueWith,以确保在WPF调度程序线程上执行.

例如:

public voID DoSomeLongRunningOperation() {    // this is called from the WPF dispatcher thread    Task.Factory.StartNew(() =>    {        // this will execute on a thread pool thread    })    .ContinueWith(t =>    {        // this will execute back on the WPF dispatcher thread    },TaskScheduler.FromCurrentSynchronizationContext()); }
总结

以上是内存溢出为你收集整理的c# – 从TPL任务向WPF视图报告进度的适当方法是什么?全部内容,希望文章能够帮你解决c# – 从TPL任务向WPF视图报告进度的适当方法是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1221892.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存