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
的原因。我问了一个特定于此
的新问题
我编写了一个自定义流 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
的原因。我问了一个特定于此