我有一个派生自Stream的类,在其读/写中,我需要访问一个数据库。我想使用SqlData对象的* Async方法但当然它希望我将Read的签名更改为具有这样的东西(我认为):
public async override Task <int> Read( byte[] buffer, int offset, int count )
这与实际签名不符,因此我收到一条编译错误消息,说明这一点。知道如何在这个流中使用* Async,或者我应该让它同步吗?
我还使用了来自https://blogs.msdn.microsoft.com/pfxteam/2011/01/15/asynclazyt/
的Stephen Toub的AsyncLazy我的课程正在启用SQL Server中VarBinary(max)字段的数据流,其中包含来自http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/的大多数想法。
以下是代码中的有趣位(异步位被注释掉):
public class BinaryDataStream<T> : Stream
{
/* Async */Lazy<SqlDataReader> lazyReader;
SqlConnection connection;
SqlCommand firstUpdate;
SqlCommand otherUpdates;
long position;
public BinaryDataStream( DbContext context, string tableName, string keyName, string columnName, T keyValue )
{
connection = new SqlConnection( context.Database.GetDbConnection().ConnectionString );
lazyReader = new /* Async */Lazy<SqlDataReader>( /* async */ () =>
{
using ( var cmd = new SqlCommand( $"SELECT TOP 1 [{columnName}] FROM [dbo].[{tableName}] WHERE [{keyName}] = @id", connection ) )
{
cmd.Parameters.AddWithValue( "@id", keyValue );
/* await */ connection.Open/* Async */();
var r = /* await */ cmd.ExecuteReader/* Async */( System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.SingleResult | System.Data.CommandBehavior.SingleRow | System.Data.CommandBehavior.CloseConnection );
r.Read();
return r;
}
} );
firstUpdate = new SqlCommand( $"UPDATE [dbo].[{tableName}] SET [{columnName}] = @firstchunk WHERE [{keyName}] = @id", connection );
firstUpdate.Parameters.AddWithValue( "@id", keyValue );
firstUpdate.Parameters.AddWithValue( "@firstchunk", new byte[] { } );
otherUpdates = new SqlCommand( $"UPDATE [dbo].[{tableName}] SET [{columnName}].WRITE( @chunk, NULL, @length ) WHERE [{keyName}] = @id", connection );
otherUpdates.Parameters.AddWithValue( "@id", keyValue );
otherUpdates.Parameters.AddWithValue( "@length", 0 );
otherUpdates.Parameters.AddWithValue( "@chunk", new byte[] { } );
}
public /* async */ override /* Task< */int/* > */ Read( byte[] buffer, int offset, int count )
{
var reader = /* await */ lazyReader.Value;
var bytesRead = reader.GetBytes( 0, position, buffer, offset, count );
position += bytesRead;
return (int)bytesRead;
}
public /* async */ override void Write( byte[] buffer, int offset, int count )
{
if ( count == 0 ) return;
/* await */ connection.Open/* Async */();
try
{
if ( firstUpdate != null )
{
firstUpdate.Parameters[ "@firstchunk" ].Value = buffer;
/* await */ firstUpdate.ExecuteNonQuery/* Async */();
firstUpdate = null;
}
else
{
var chunk = buffer;
if ( count < buffer.Length )
{
chunk = new byte[ count ];
Array.Copy( buffer, 0, chunk, 0, count );
}
otherUpdates.Parameters[ "@chunk" ].Value = chunk;
otherUpdates.Parameters[ "@length" ].Value = count;
/* await */ otherUpdates.ExecuteNonQuery/* Async */();
}
}
finally
{
connection.Close();
}
}
}
答案 0 :(得分:2)
Stream
类具有其方法的同步和异步版本。同样,您执行的数据库操作也会暴露其方法的同步和异步版本。使用同步实现覆盖同步方法,并使用异步实现覆盖异步方法。