如何跟踪从 SQL Server 下载文件的进度?
Posted
技术标签:
【中文标题】如何跟踪从 SQL Server 下载文件的进度?【英文标题】:How can I track the progress of a file being downloaded from SQL Server? 【发布时间】:2017-08-01 16:33:41 【问题描述】:我的 winforms 应用程序正在接收来自 SQL Server 的文件,我想以进度条的形式显示该文件的下载量。
为了检索文件,我调用了一个存储过程并将结果保存到一个字节数组中:
Dim file() as Byte = SQLCommand.ExecuteScalar()
这很好用,对于较小的文件,我真的不需要进度条,因为它们完成得如此之快。但是,有些文件可能会变得很大,有些连接可能不是很好,所以我真的认为我需要某种进度指示。
我了解我可能需要使用后台工作线程,并且我了解如何执行此操作。但是,如何定期检查已收到多少文件,就像我这样,它似乎在一大块中执行操作?
这样可以吗?还是我需要检查我是如何完整接收文件的?
我的应用程序是 VB.Net,但 C# 答案完全可以接受。
【问题讨论】:
由于您的编码语言是 VB.NET,您认为这个问题及其答案可以帮助您解决这个问题吗?我不认为这个问题是重复的,我只是对发布答案的过程知之甚少。 ***.com/questions/16688990/… 查看docs.microsoft.com/en-us/dotnet/framework/data/adonet/…和docs.microsoft.com/en-us/dotnet/api/… @KanstantsinArlouski 感谢您的建议。实际上,在您发表评论之前,我才刚刚读过。不幸的是,这并没有多大帮助,因为在那个问题中,它们正在处理大量行,而不是单个大 BLOB 数据。 【参考方案1】:见SqlClient Streaming Support。你需要做几个步骤:
在您的 Execute 调用中指定CommandBehavior.SequentialAccess
使用SqlDataReaderGetStream
方法访问字段值
使用 Stream API(例如Stream.Read
)读取内容,这样您就可以知道自己在这个过程中走了多远。
链接的文章显示了有关如何完成流式传输部分的更多详细信息,之后添加进度条是微不足道的。
【讨论】:
谢谢。显然,我有很多关于 async/await 的阅读。我对 BackgroundWorker 比较熟悉,所以对我来说有点新。我仍然不完全理解它,但我认为它足以让我得到一些工作。 @Gravitate 您不需要将 async/await 添加到等式中。同步 API 也应该可以工作。但是,如果您在进程中加快了 async/await 的速度并改用它,那么一定要坚持下去,会好得多。【参考方案2】:您可以将 .NET 4.5 中的流式传输功能与异步编程模型结合使用。
private static async Task CopyBinaryValueToFile()
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "binarydata.bin");
using (SqlConnection connection = new SqlConnection(connectionString))
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT [bindata] FROM [Streams] WHERE [id]=@id", connection))
command.Parameters.AddWithValue("id", 1);
// The reader needs to be executed with the SequentialAccess behavior to enable network streaming
// Otherwise ReadAsync will buffer the entire BLOB into memory which can cause scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
if (await reader.ReadAsync())
if (!(await reader.IsDBNullAsync(0)))
using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
using (Stream data = reader.GetStream(0))
// Asynchronously copy the stream from the server to the file we just created
await data.CopyToAsync(file);
看到这个: sqlclient-streaming-support
【讨论】:
谢谢,但这如何让我跟踪进度?以上是关于如何跟踪从 SQL Server 下载文件的进度?的主要内容,如果未能解决你的问题,请参考以下文章