如何在不缓冲的情况下将文件从数据库异步传输到webclient

我正在尝试使用.net 4.5和web api将文件从sql server异步流式传输到Web客户端。

我正在使用SqlDataReader.GetStream()从数据库中获取流。 但是,当webapi从流中读完时,我不确定如何连接数据库连接的处理/关闭。

有样品吗?

您可以编写一个从底层流中读取的包装流,直到它耗尽,然后处理所有相关资源(如SqlConnection)。

我不是WebAPI专家,所以可能有一种更优雅的方式来做到这一点。 但无论如何,这都适用于流的标准WebAPI支持。

您可以在Web API中执行类似的操作。 在这里,我使用PushStreamContent连接到数据库并检索Sql流。 然后我直接将此sql流复制到响应流。 在Web API中,当您使用PushStreamContent时,客户端将以分块传输编码接收响应,因为您没有设置响应的内容长度。 如果这对你没问题,你可以使用下面的例子。 否则我会试着看看是否还有其他更好的方法来实现这一目标。

注意:这是一个基于PushStreamContent和MSDN上关于从sql server检索二进制数据的文章的快速示例。

 [RoutePrefix("api/values")] public class ValuesController : ApiController { private const string connectionString = @"your connection string"; [Route("{id}")] public HttpResponseMessage GetImage(int id) { HttpResponseMessage resp = new HttpResponseMessage(); resp.Content = new PushStreamContent(async (responseStream, content, context) => { await CopyBinaryValueToResponseStream(responseStream, id); }); return resp; } // Application retrieving a large BLOB from SQL Server in .NET 4.5 using the new asynchronous capability private static async Task CopyBinaryValueToResponseStream(Stream responseStream, int imageId) { // PushStreamContent requires the responseStream to be closed // for signaling it that you have finished writing the response. using (responseStream) { 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", imageId); // 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 (Stream data = reader.GetStream(0)) { // Asynchronously copy the stream from the server to the response stream await data.CopyToAsync(responseStream); } } } } } } }// close response stream } }