代码之家  ›  专栏  ›  技术社区  ›  Sean Hanley

如何在使用ado.net时最好地显示进度信息?

  •  2
  • Sean Hanley  · 技术社区  · 16 年前

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

    目前,我使用内存中的数据表和数据行,然后通过TableAdapter.update调用与数据库同步。这工作得很好,很好,但是一次调用几乎没有机会收集任何类型的进度信息显示给用户。我不知道有多少数据通过网络传输到远程数据库或其进程。基本上,我只知道当update返回时,它被认为是完整的(除非有任何错误或异常)。但这意味着我只能显示0%,然后暂停,然后100%。

    我可以计算行数,甚至可以计算实际修改或添加的行数,甚至可以根据每个列的数据类型计算每个数据行的估计大小,对值类型(如int)使用size of,并检查字符串或字节数组等的长度。有了这个,我可能在更新之前就可以确定估计的总传输大小,但是一旦在tableadapter上调用update,我仍然无法获得任何进度信息。

    我被困在一个不确定的进度条或鼠标等待光标?我是否需要彻底改变我们的数据访问层,以便能够钩住这种信息?即使我不能把它降到精确的KB传输(比如Web浏览器文件下载进度条),我能至少知道每一个数据行/数据表什么时候完成吗?

    如何使用ado.net最好地显示这种进度信息?

    2 回复  |  直到 16 年前
        1
  •  1
  •   Aaronaught    16 年前

    有一个半解决方案 SELECT 部分,它将发布 COUNT 首先查询以获取预期接收的行数。只有当 伯爵 查询可以非常快地返回结果(即在几秒钟内),另一方面,如果运行需要几秒钟,那么查询执行本身(与结果枚举相反)可能需要比数据传输更长的时间,在这种情况下,不值得尝试显示离散的进程酒吧。

    至于 UPDATE INSERT -不,没有任何简单的解决方案,特别是使用tableadapters。如果有大量数据要发送,您可能需要考虑使用 SqlBulkCopy 类以上载到临时表,然后在服务器上执行实际更新。那个班提供 NotifyAfter 财产连同 SqlRowsCopied 事件,它可以为您提供当前进度的合理近似值(在本例中,您已经知道行的总数,因为它们在内存中)。

    当然,这需要对当前的TableAdapter实现进行重大更改,但.NET中的类型化数据集系统实际上并不是设计用来处理除LAN连接以外的任何其他大小的记录集的。

    我认为大多数人只会选择使用一个天棚进度条。现在的用户希望如此;即使您能够准确地预测行数和数据传输速率,您仍然不知道查询实际执行需要多长时间,特别是在服务器负载很重的情况下,而且提供 bad estimates 比没有估计的要多。

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

        2
  •  0
  •   John Saunders    16 年前

    正如aaronaught所说的那样-带有notifyafter的sqlbulkcopy应该可以工作(不过对我来说是工作的)。

    我不认为这会对你当前的dal实现有“重大改变”…