Stream.CopyToAsync 从不调用我的 WriteAynsc 方法

Stream.CopyToAsync never calls my WriteAynsc method

我编写了一个自定义流 class,需要将数据库命中 read/write 信息。我想使用 XxAsync 数据库方法,因此建议我在我的流中同时编写同步和异步方法,因为我无法在我的同步 Read/Write 方法中使用 connection.OpenAsync()

但是,在实现这两个版本之后,当我在一个简单的控制台应用程序的 void Main() 方法中使用此流作为调用的目标时,如下所示:

Task.Run( async () =>
{
    using ( var ctx = new JobContext() )
    {
        // create AssemblyCache record and get assemblyKey...

        using ( var fs = new System.IO.FileStream( @"C:\BTR\Source\Assemblies\BTR.Rbl.Evolution.Documents.dll",
                                    System.IO.FileMode.Open,
                                    System.IO.FileAccess.Read,
                                    System.IO.FileShare.None,
                                    8192,
                                    true ) )
        using ( var bs = ctx.GetBinaryWriteStream<AssemblyCache>( assemblyKey ) )
        {
            await fs.CopyToAsync( bs );
        }
    }
} ).Wait();

它似乎从未调用我的 XxAsync 方法。我只跟踪同步版本。查看 Stream base class 的源代码,看起来 CopyToAsync 应该调用我的 WriteAsync 方法,所以我不确定我遗漏了什么。

您可以使用 SqlClient's streaming support 将数据从客户端流式传输到服务器上的 BLOV(即 varbinary(MAX))列。您使用与执行 INSERT 时几乎相同的代码,但不是使用将值传递给 SQL 命令,而是传递流或流 reader。例如,而不是使用

var sql="INSERT INTO [MyTable] (blobField) VALUES (@data)"
using (SqlConnection conn = new SqlConnection(connectionString)) 
using (SqlCommand cmd = new SqlCommand(sql, conn)) 
{
    cmd.Parameters.Add("@data", SqlDbType.Binary, myBuffer.Length).Value = myBuffer;
    await conn.OpenAsync();
     await cmd.ExecuteNonQueryAsync();
}

你会写

var sql="INSERT INTO [MyTable] (blobField) VALUES (@data)"
using (SqlConnection conn = new SqlConnection(connectionString)) 
using (SqlCommand cmd = new SqlCommand(sql, conn)) 
{
    await conn.OpenAsync();
    using (FileStream file = File.Open("binarydata.bin", FileMode.Open)) 
    {
        cmd.Parameters.Add("@data", SqlDbType.Binary, -1).Value = file;
        await cmd.ExecuteNonQueryAsync();
     }
}

如果要发送很多文件,可以在循环中给参数赋值流:

    var blobParam=cmd.Parameters.Add("@data", SqlDbType.Binary, -1);
    foreach(var somePath in aListOfPaths)
    {
        using (FileStream file = File.Open(somePath, FileMode.Open)) 
        {
            blobparam.Value = file;
            await cmd.ExecuteNonQueryAsync();
         }
     }

原来我的 GetBinaryWriteStream 扩展(有意地)在我的自定义流周围包装了一个 GZipStream 以支持压缩。 GZipStream 是未调用 WriteAsync 的原因。我问了一个特定于此

的新问题