简体   繁体   English

频繁,可取消的异步大文件读取操作(.NET 4.0)

[英]Frequent, cancellable, asynchronous large-file read operations (.NET 4.0)

My application graphically visualizes very large files. 我的应用程序以图形方式显示了很大的文件。 The user can zoom in and use a scrollbar to move over it. 用户可以放大并使用滚动条在其上移动。 Because accessing file contents would cause UI delays and piss off the user, file access needs to be done from a separate thread. 由于访问文件内容会导致UI延迟并激怒用户,因此文件访问需要从单独的线程进行。

Case: user moves scrollbar: 案例:用户移动滚动条:

  • the thread (start a new one each time?) must load data in the background to update the view for the new scrollbar position 该线程(每次启动一个新线程?)必须在后台加载数据以更新新滚动条位置的视图
  • if a prior request is in progress: that must be cancelled 如果正在处理先前的请求:必须将其取消
  • when it has loaded the data it must return the result to the UI for display 加载数据后,必须将结果返回到UI进行显示

For file access I will use the MemoryMappedFile class. 对于文件访问,我将使用MemoryMappedFile类。 Maybe it's thread safe, but I think it's better to completely stop a previous read operation before starting a new one (no overlap, sequential ). 也许它是线程安全的,但我认为最好在开始新操作之前完全停止先前的读取操作(无重叠, 顺序 )。

I was thinking cancelling requests using CancellationTokenSource s. 我当时正在考虑使用CancellationTokenSource取消请求。 But a scrollbar generates many events. 但是滚动条会生成许多事件。 Are we supposed to new and cancel tens or hundreds of CancellationTokenSource s in a short time? 我们是否应该在短时间内new并取消数十或数百个CancellationTokenSource ( frequent starting/cancelling ) 频繁启动/取消

There's an overhead starting a thread, even with a thread pool. 即使使用线程池,启动线程也有开销。 So it's better to have a thread ready, waiting for work posted to it. 因此,最好准备好一个线程,等待发布的工作。 Dispatcher ? Dispatcher

BackgroundWorker may have the overlap problem if you starting a new one each time. 如果您每次都启动一个新的BackgroundWorker可能会出现重叠问题。 But that's how it's supposed to be used... 但这就是应该使用的方式...

'async' 'await' : I hear this is very good for IO, but I'm on .NET 4.0 so it's not available for me. 'async''await':我听说这对IO非常有用,但是我在.NET 4.0上,因此对我不可用。

So now I'm thinking a Thread with Dispatcher , and CancellationTokenSource to cancel requests. 所以现在我正在考虑使用DispatcherCancellationTokenSourceThread来取消请求。 But maybe there's a better way? 但是也许有更好的方法?

This question as stated seems way too broad; 如前所述,这个问题似乎过于笼统。 it lacks any context (ie what have you tried so far, what specific problem did you have?) and there are far too many different questions. 它没有任何上下文(例如,到目前为止您尝试过什么,您遇到了什么具体问题?)并且有太多不同的问题。 So, let's assume we constrain the scope of the question to something that is of reasonable breadth for Stack Overflow. 因此,假设我们将问题的范围限制为对于Stack Overflow具有合理广度的问题。

As such, in terms of the posted question above, only brief comments regarding those questions would be appropriate: 因此,就上述发布的问题而言,仅对这些问题进行简短评论是合适的:


MemoryMappedFile

That class does not offer asynchronous access at all, so I don't know why it's even here, never mind why you've chosen it as your underlying implementation. 该类根本不提供异步访问,所以我不知道为什么它还在这里,不要介意为什么选择它作为基础实现。

"scrollbar generates many events" “滚动条产生许多事件”

One typically does not initiate costly operations (computation or I/O) in response to every UI input; 通常,不会响应于每个UI输入来启动代价高昂的操作(计算或I / O)。 instead, you wait a small period of time, and only start after that. 相反,您需要等待一小段时间,然后再开始。 This will dramatically reduce the number of operations started as the user provides input (eg manipulates the scroll bar); 随着用户提供输入(例如,操纵滚动条),这将大大减少开始的操作数量。 if you make the delay long enough, you'll almost never have to interrupt an asynchronous operation that's in progress. 如果使延迟时间足够长,则几乎无需中断正在进行的异步操作。

"overhead...even with a thread pool" “开销……甚至有线程池”

Huh? 咦? what is a thread pool other than an implementation in which there's "a thread ready, waiting for work posted to it" , just as you propose to implement yourself? 什么是线程池,而不是像您打算自己实现的那样,其中有一个“线程就绪,正在等待发布的工作”的实现?

There is not going to be any overhead using ThreadPool that you would not yourself introduce were you to reinvent the thread pool yourself. 如果您自己重新创建线程池,那么使用ThreadPool不会产生任何开销,您不会自己引入这些开销。

BackgroundWorker may have the overlap problem BackgroundWorker可能有重叠问题

What overlap problem? 什么重叠问题? The same exact one you'd have with any other asynchronous implementation, ie that one operation is in progress when you want to start another? 您可以与其他异步实现实现相同的功能,即要启动另一个操作时正在执行一个操作?

BackgroundWorker is just another way to implement background tasks, which in turn are one way to implement certain kinds of asynchronous operations. BackgroundWorker只是实现后台任务的另一种方式,而后台任务又是实现某些类型的异步操作的一种方式。 The main benefit of BackgroundWorker isn't that it encapsulates a task; BackgroundWorker的主要好处不是封装任务。 the ThreadPool does that fine all by itself. ThreadPool本身就可以完成所有工作。 What BackgroundWorker offers is events that are raised in the synchronization context in which the object was created (eg the UI thread), to simplify reporting of progress, cancellation, and completion. BackgroundWorker提供的是在创建对象的同步上下文中引发的事件(例如,UI线程),以简化进度,取消和完成的报告。

If there's an "overlap problem" at all, it's nothing that doesn't also exist with any other asynchronous code you might implement. 如果有一个“重叠问题”,那么您可能实现的任何其他异步代码都不存在。

async / await async / await

This C# 5 feature does not in and of itself solve any asynchronous problem. C#5功能本身并不能解决任何异步问题。 It is simply a syntactical way to leverage the compiler's ability to vastly simplify how asynchronous code is written. 这只是一种语法方法,可以利用编译器的功能大大简化异步代码的编写方式。 The features works with actual asynchronous implementations, not as some alternative to those. 这些功能可用于实际的异步实现,而不是替代这些实现的替代方法。


It is my hope that the points above help you in your path to coming up with an actual implementation of whatever it is you're trying to do. 我希望以上几点能帮助您提出实际的实施方案,以解决您要执行的操作。 If and when you have actual code and run into some specific problem that you need help with, please do post a new question, including a good, minimal , complete code example that reliably reproduces whatever problem you are having, along with a precise, detailed explanation of what that code does and how that's different from what you want. 如果并且当您有实际的代码并遇到需要帮助的特定问题时,请发布新问题,包括一个好的, 最小的完整的代码示例 ,该示例可以可靠地重现您遇到的任何问题,并提供精确,详细的信息该代码的功能以及与您想要的功能有何不同的说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM