使用 ADO.NET 时如何最好地显示进度信息?

发布于 2024-08-28 12:19:24 字数 615 浏览 5 评论 0原文

我想在执行可能很长的数据库操作时向用户显示详细的进度信息。具体来说,当插入/更新可能约为数百 KB 或 MB 的数据时。

目前,我使用内存中的 DataTables 和 DataRows,然后通过 TableAdapter.Update 调用与数据库同步。这工作得很好,但单个调用几乎没有机会收集任何类型的进度信息以显示给用户。我不知道有多少数据通过网络传递到远程数据库或其进度。基本上,我所知道的是更新何时返回并且假定已完成(除非有任何错误或异常)。但这意味着我只能显示 0%,然后暂停,然后是 100%。

我可以计算行数,甚至可以计算出实际修改或添加的行数,我什至可以根据每列的数据类型计算每个 DataRow 的估计大小,使用 sizeof 作为 int 等值类型并检查字符串或字节数组等内容的长度。这样,我可能可以在更新之前确定估计的总传输大小,但是一旦在 TableAdapter 上调用 Update,我仍然没有任何进度信息。

我是否只是使用不确定的进度条或鼠标等待光标而陷入困境?我是否需要从根本上改变我们的数据访问层才能连接到此类信息?即使我无法将其精确到传输的 KB(如 Web 浏览器文件下载进度条),我至少可以知道每个 DataRow/DataTable 何时完成或其他什么吗?

如何使用 ADO.NET 最好地显示此类进度信息?

I want to show the user detailed progress information when performing potentially lengthy database operations. Specifically, when inserting/updating data that may be on the order of hundreds of KB or MB.

Currently, I'm using in-memory DataTables and DataRows which are then synced with the database via TableAdapter.Update calls. This works fine and dandy, but the single call leaves little opportunity to glean any kind of progress info to show to the user. I have no idea how much data is passing through the network to the remote DB or its progress. Basically, all I know is when Update returns and it is assumed complete (barring any errors or exceptions). But this means all I can show is 0% and then a pause and then 100%.

I can count the number of rows, even going so far to cound how many are actually Modified or Added, and I could even maybe calculate per DataRow its estimated size based on the datatype of each column, using sizeof for value types like int and checking length for things like strings or byte arrays. With that, I could probably determine, before updating, an estimated total transfer size, but I'm still stuck without any progress info once Update is called on the TableAdapter.

Am I stuck just using an indeterminate progress bar or mouse waiting cursor? Would I need to radically change our data access layer to be able to hook into this kind of information? Even if I can't get it down to the precise KB transferred (like a web browser file download progress bar), could I at least know when each DataRow/DataTable finishes or something?

How do you best show this kind of progress info using ADO.NET?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄断弥空 2024-09-04 12:19:24

对于 SELECT 部分有一个半解决方案,即首先发出 COUNT 查询来获取您期望接收的行数。仅当 COUNT 查询可以非常快地返回结果(即不到一秒)时,这才实用 - 另一方面,如果运行需要几秒钟,则查询执行本身( (与结果枚举相反)可能比数据传输花费的时间更长,在这种情况下,根本不值得尝试显示离散的进度条。

至于 UPDATEINSERT - 不,实际上没有任何简单的解决方案,尤其是使用 TableAdapters。如果您有大量数据要发送,您可能需要考虑使用 SqlBulkCopy 类上传到临时表,然后在服务器上执行实际更新。该类提供 NotifyAfter 属性以及 SqlRowsCopied 事件可以为您提供当前进度的合理近似值(在这种情况下您已经知道行总数,因为它们在内存中)。

当然,这需要对当前的 TableAdapter 实现进行重大更改,但 .NET 中的类型化数据集系统实际上并不是为了通过 LAN 连接以外的任何方式处理该大小的记录集而设计的。

我认为大多数人只会选择使用字幕进度条。如今,用户期望这一点;即使您可以准确地预测行数和数据传输速率,您仍然不知道查询实际执行需要多长时间,特别是在服务器负载很重的情况下,并且可以说提供< a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.sqlrowscopied%28v=VS.90%29.aspx" rel="nofollow noreferrer">错误估计< /a> 比没有估计。

如果查询(或更新)本身很可能需要很长时间在服务器本身上运行,而不计算上传/下载记录的任何时间,那么我肯定会使用字幕进度条。否则……祝你好运。

There's a semi-solution for the SELECT part, which is to issue a COUNT query first to get the number of rows you expect to receive. This is only practical if the COUNT query can return a result very fast (i.e. in a fraction of a second) - on the other hand, if it takes several seconds to run, then the query execution itself (as opposed to result enumeration) might take longer than the data transfer, in which case it's not worth trying to show a discrete progress bar at all.

As for UPDATE and INSERT - no, there's not really any simple solution for that, especially using TableAdapters. If you have a huge amount of data to send, you might want to consider using the SqlBulkCopy class to upload to a staging table and then perform the actual update on the server. That class offers the NotifyAfter property along with the SqlRowsCopied event which can give you a reasonable approximation of the current progress (you already know the total number of rows in this case, since they're in memory).

That will of course require significant changes from your current TableAdapter implementation, but the typed dataset system in .NET really wasn't designed to handle recordsets of that size over anything other than a LAN connection.

I think that most people would simply choose to use a marquee progress bar. Users expect this nowadays; even if you could accurately predict the number of rows and the data transfer rate, you still have no idea how long it's going to take for the query to actually execute, especially if the server is under heavy load, and it's arguably worse to provide bad estimates than no estimates.

If there's a realistic chance that the query (or update) itself will take a long time to run on the server itself, not counting any time to upload/download the records, then I would definitely use a marquee progress bar instead. Otherwise... good luck.

执笏见 2024-09-04 12:19:24

正如 Aaronaught 所说 - SqlBulkCopy 与 NotifyAfter 应该有效(但它对我有效)。

我不认为这会对您当前的 DAL 实现产生“重大改变”......

As Aaronaught said - SqlBulkCopy with NotifyAfter should work (it works for me though).

I don't think this would be 'significant change' to your current DAL implementation...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文