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

时间:2010-04-10 02:11:05

标签: .net ado.net progress-bar

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

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

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

我是否只是使用不确定的进度条或鼠标等待光标?我是否需要从根本上改变我们的数据访问层以便能够挂钩这种信息?即使我无法将其转移到精确的KB转移(如网络浏览器文件下载进度条),我至少可以知道每个DataRow / DataTable何时完成?

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

2 个答案:

答案 0 :(得分:1)

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

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

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

我认为大多数人会选择使用选框进度条。用户现在期待这一点;即使您可以准确地预测行数和数据传输速率,您仍然不知道查询实际执行需要多长时间,特别是如果服务器负载很重,并且提供{可能会更糟糕{3}}比没有估计值。

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

答案 1 :(得分:0)

正如Aaronaught所说 - 带有NotifyAfter的SqlBulkCopy应该可以工作(虽然它适用于我)。

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