【问题标题】:Frequent, cancellable, asynchronous large-file read operations (.NET 4.0)频繁、可取消的异步大文件读取操作 (.NET 4.0)
【发布时间】:2015-11-06 17:49:19
【问题描述】:

我的应用程序以图形方式可视化非常大的文件。用户可以放大并使用滚动条在其上移动。因为访问文件内容会导致 UI 延迟和惹恼用户,文件访问需要从单独的线程完成。

案例:用户移动滚动条:

  • 线程(每次都启动一个新线程?)必须在后台加载数据以更新新滚动条位置的视图
  • 如果先前的请求正在进行中:必须取消
  • 加载数据后,必须将结果返回给 UI 以供显示

对于文件访问,我将使用MemoryMappedFile 类。也许它是线程安全的,但我认为在开始新的读取操作之前最好完全停止以前的读取操作(无重叠,顺序)。

我正在考虑使用CancellationTokenSources 取消请求。但是滚动条会产生很多事件。我们是否应该在短时间内new 并取消数十或数百个CancellationTokenSources? (频繁启动/取消

即使使用线程池,启动线程也会产生开销。所以最好准备好一个线程,等待发布到它的工作。 Dispatcher?

BackgroundWorker 如果每次都开始一个新的,可能会出现重叠问题。但这就是它应该被使用的方式......

'async' 'await' :我听说这对 IO 非常有用,但我在 .NET 4.0 上,所以它不适合我。

所以现在我想用ThreadDispatcherCancellationTokenSource 来取消请求。但也许有更好的方法?

【问题讨论】:

  • 你见过微软的 bcl.async 包吗?它允许您从 .net 4.0 使用异步和等待。我已经在生产代码中使用了它,它对我来说是可靠的。有一个 nuget:link 一些警告——在 .net 4.5 中添加到 Task 的静态辅助方法丢失了,但 Task.Factory.StartNew() 完成了工作。

标签: c# wpf multithreading io .net-4.0


【解决方案1】:

如前所述,这个问题似乎太宽泛了;它缺乏任何上下文(即到目前为止您尝试了什么,您遇到了什么具体问题?)并且有太多不同的问题。因此,假设我们将问题的范围限制在 Stack Overflow 的合理范围内。

因此,就上面发布的问题而言,只有关于这些问题的简短 cmet 是合适的:


MemoryMappedFile

那个类根本不提供异步访问,所以我什至不知道它为什么会在这里,更不用说你为什么选择它作为你的底层实现了。

“滚动条产生很多事件”

通常不会启动昂贵的操作(计算或 I/O)来响应每个 UI 输入;相反,您等待一小段时间,然后才开始。这将大大减少用户提供输入时启动的操作数量(例如,操纵滚动条);如果延迟足够长,您几乎不需要中断正在进行的异步操作。

“开销......即使有线程池”

嗯?除了“一个线程准备好,等待发布给它的工作”的实现之外,什么是线程池,就像您建议自己实现一样?

如果您自己重新发明线程池,使用 ThreadPool 不会产生任何开销。

BackgroundWorker可能有重叠问题

什么重叠问题?与任何其他异步实现完全相同的操作,即当您想要启动另一个操作时,一个操作正在进行中?

BackgroundWorker 只是实现后台任务的另一种方式,而后者又是实现某些异步操作的一种方式。 BackgroundWorker 的主要好处不是它封装了一个任务。 ThreadPool 本身就可以做到这一点。 BackgroundWorker 提供的是在创建对象的同步上下文(例如 UI 线程)中引发的事件,以简化进度、取消和完成的报告。

如果根本存在“重叠问题”,那么您可能实现的任何其他异步代码都不存在。

async/await

这个 C# 5 特性本身并不能解决任何异步问题。它只是一种利用编译器极大简化异步代码编写方式的能力的语法方式。这些功能实际的异步实现一起工作,而不是作为那些的替代品。


我希望以上几点可以帮助您找到实际实施的任何您正在尝试做的事情。如果并且当您有实际代码并遇到一些需要帮助的特定问题时,请发布一个新问题,包括a good, minimal, complete code example,它可以可靠地重现您遇到的任何问题,以及精确的,详细说明该代码的作用以及与您想要的有何不同。

【讨论】:

  • 好点,它有助于澄清我的一些误解。在编写代码之前,有时我会遇到这些“绘图表”问题。我想知道是否有针对此类问题的 stackexchange 站点,因为 SO 在实际代码中更“显示您尝试过的内容”。
  • @KayZed:我不确定,但我认为programmers.stackexchange.com 可能更适合这类问题。
猜你喜欢
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-03
相关资源
最近更新 更多