频繁的、可取消的、异步的大文件读取操作(.NET 4.0)
本文关键字:NET 操作 文件 可取消 异步 读取 | 更新日期: 2023-09-27 18:20:50
我的应用程序以图形方式可视化非常大的文件。用户可以放大并使用滚动条在其上移动。由于访问文件内容会导致UI延迟并激怒用户,因此需要从单独的线程进行文件访问。
案例:用户移动滚动条:
- 线程(每次启动一个新线程?)必须在后台加载数据,以更新新滚动条位置的视图
- 如果先前的请求正在进行中:则必须取消
- 加载数据后,必须将结果返回到UI以进行显示
对于文件访问,我将使用MemoryMappedFile
类。也许这是线程安全的,但我认为在开始新的读取操作之前最好完全停止以前的读取操作(没有重叠,顺序)。
我想用CancellationTokenSource
s取消请求。但是滚动条会生成许多事件。我们应该在短时间内new
并取消几十个或数百个CancellationTokenSource
吗?(频繁启动/取消)
即使使用线程池,启动线程也会有开销。因此,最好准备好一个线程,等待向其发布的工作。Dispatcher
?
如果每次都启动一个新的BackgroundWorker
,则可能会出现重叠问题。但它应该是这样使用的。。。
"async"wait":我听说这对IO很好,但我使用的是.NET 4.0,所以它对我不可用。
所以现在我想用Thread
、Dispatcher
和CancellationTokenSource
来取消请求。但也许还有更好的方法?
这个问题似乎太宽泛了;它缺乏任何上下文(即,到目前为止你尝试了什么,你有什么特定的问题?)并且有太多不同的问题。因此,让我们假设我们将问题的范围限制在堆栈溢出的合理范围内。
因此,就上面发布的问题而言,只对这些问题发表简短评论是合适的:
MemoryMappedFile
该类根本不提供异步访问,所以我不知道它为什么会出现在这里,更不用说为什么选择它作为底层实现了。
"滚动条生成许多事件"
一种典型地不响应于每个UI输入而启动昂贵的操作(计算或I/O);相反,你要等待一小段时间,然后才开始。这将显著减少当用户提供输入(例如操纵滚动条)时开始的操作数量;如果您使延迟足够长,那么您几乎永远不必中断正在进行的异步操作。
"开销…即使使用线程池"
嗯?什么是线程池,而不是实现中有"一个线程准备好了,正在等待发布到它的工作",就像你打算自己实现一样?
使用ThreadPool
不会有任何开销,如果您自己重新设计线程池,您不会自己介绍这些开销。
BackgroundWorker
可能存在重叠问题
什么重叠问题?与任何其他异步实现完全相同,即当您想启动另一个操作时,一个操作正在进行中?
BackgroundWorker
只是实现后台任务的另一种方式,而后台任务又是实现某些异步操作的一种方式。BackgroundWorker
的主要优点不在于它封装了一个任务;CCD_ 15本身就完成了这一切。BackgroundWorker
提供的是在创建对象的同步上下文(例如UI线程)中引发的事件,以简化进度、取消和完成的报告。
如果存在"重叠问题",那么您可能实现的任何其他异步代码都不存在这种问题。
async
/await
这个C#5特性本身并不能解决任何异步问题。这只是一种利用编译器能力极大简化异步代码编写方式的语法方法。这些功能与实际的异步实现协同工作,而不是作为这些功能的替代方案。
我希望以上几点能帮助你找到你想要做的事情的实际实现。如果你有实际的代码,遇到了一些特定的问题,你需要帮助,请发布一个新的问题,包括一个好的最小、完整代码示例,它可靠地再现了你所遇到的任何问题,以及对该代码的作用以及与您想要的不同之处的精确、详细的解释。