- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图以小“ block ”或页面的形式从数据库中读取大量行,并向用户报告进度;即,如果我正在加载 100 个“ block ”,则在加载每个 block 时报告进度。
我正在使用 C# 4.0 中的 TPL 从数据库中读取这些 block ,然后将完整的结果集交给另一个可以使用它的任务。我觉得与 BackgroundWorker 等相比,TPL 可以更好地控制任务取消和移交,但似乎没有内置的方式来报告任务的进度。
这是我为向 WPF 进度条报告进度而实现的解决方案,我想确保这是合适的并且没有更好的方法我应该采用。
我首先创建了一个简单的界面来表示不断变化的进度:
public interface INotifyProgressChanged
{
int Maximum { get; set; }
int Progress { get; set; }
bool IsIndeterminate { get; set; }
}
这些属性可以绑定(bind)到 WPF View 中的 ProgressBar,接口(interface)由负责启动数据加载并最终报告总体进度的支持 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 接口(interface),以便报告最终更新 View 的进度。下面是存储库方法的快速浏览(在此示例中已缩短):
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 View 报告进度的适当方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6684580/
我有以下 TPL 数据流,当使用谓词过滤从 TransformBlock 传递到 ActionBlock 的项目时,它永远不会完成。 如果谓词对任何项目返回 false,则数据流挂起。 请有人提供一些
我是 smarty 的新手,所以我不确定这是否会导致我遗漏某些内容,但目前我正在尝试从 css 文件中提取一个类。 到目前为止,我已经设置了 2 个类 mainbackground 和 body,ma
如何强制 TPL 使用固定数量的线程?我知道 MaxDegreeOfParallelism 可用于设置上限,但我希望上限等于下限。这可能吗?怎么办? 因为我知道有人会问 =) 是的,我确定我想这样做,
我正在尝试使用 GXT 3.0 的 XTemplates(类似于 EXT),这里有 2 个具有以下关系的简单 java 对象: class A { String name; public
我刚刚将 Visual Studio 11 Beta 升级到新的 Visual Studio 2012 RC,并且在引用 TPL 数据流时遇到了问题。 首先,我尝试像以前一样通过从框架中添加引用来引用
我需要制作可扩展的流程。该进程主要有 I/O 操作和一些次要的 CPU 操作(主要是反序列化字符串)。该过程在数据库中查询 url 列表,然后从这些 url 中获取数据,将下载的数据反序列化为对象,然
我们有一个 TPL 数据流管道,其中包含以下 block : 变换 block A:Http post call 转换 block B:数据库 IO Transform Block C:一些单位转换数
我有一个 BufferBlock 来发布消息: public class DelimitedFileBlock : ISourceBlock { private ISourceBlock _s
我想在 Windows Azure 上的工作进程中使用 TPL。我希望在队列中添加一个 IJob,它有一个 Run 方法,因此工作线程将包括: 循环 将项目从队列中取出 使用TPL调用IJob.Run
我尝试创 build 计良好的 TPL 数据流管道,以优化系统资源的使用。我的项目是一个 HTML 解析器,它将解析后的值添加到 SQL Server DB 中。我已经有了 future 管道的所有方
我想为特定的内容类型覆盖 page.tpl.php。 我已经尝试过这些东西,对我没有任何作用。 page--article.tpl.php page--node--article.tpl.php pa
我已经完成了这个 POC 并验证了当你创建 4 个线程并在四核机器上运行它们时,所有的核心都会变得忙碌——所以,CLR 已经在不同的核心上有效地调度了线程,那么为什么要使用 TASK 类呢? 我同意
使用Visual Studio Concurrency Visualizer我现在明白为什么切换到 Parallel.For 没有任何好处:只有 9% 的时间机器忙于执行代码,其余的时间为 71% 的
我的代码中有以下使用 TPL 的设置: 我的类中的一个字段:private CancellationTokenSource _cancellationTokenSource; 每次我创建使用特定取消
我有一个 Windows 服务,它在经过漫长的过程后发送电子邮件。每当有表条目并处理它并将其发送出去时,该服务就会继续从数据库表中获取电子邮件数据。 目前它是一个多线程应用程序,我们在生产服务器中将线
刚刚使用 TPL DataFlow 编写了示例生产者消费者模式。我在这里有一些基本问题。 只有在生产者发布所有项目后,消费者才处于事件状态。异步是指生产任务和消费任务都可以并行运行。 给消费者一个 s
我正在使用 TPL,需要有一个长时间运行的 TPL 任务将结果发送到父 UI 线程而不终止。我已经尝试了几种方法,并且已经在谷歌上搜索了很多。有谁知道如何通过 TPL 实现这一点? 最佳答案 您可以传
我有一个以这种方式设置的 TPL 数据流: 下载字节数组 处理数据 将处理后的数据流式传输到另一个位置 此流程运行良好,但偶尔会在下载文件时遇到备份、连接问题等。我想做的是并行下载,但仍确保执行第 3
我有一个应该批量调用并压缩大文件的控制台应用程序,我想使用 DataFlow,除了完成之外一切正常 请考虑以下代码 public static void CompressFiles(string fo
当你生成多个任务时,像这样: for (int i = 0; i ((stateObject) => { tls.Value = (int)stateObject;
我是一名优秀的程序员,十分优秀!