나는 스트림에서 파생 된 클래스가 있고 해당 읽기/쓰기, 나는 데이터베이스에 충돌해야합니다. 나는 SQLDATA 객체의 * 비동기 방법을 사용하고 싶어하지만 물론이 같은 (내 생각)에 비동기 수정을 가지고 읽기의 서명을 변경하는 나를 원하는 :다른 비동기 메서드를 호출하는 사용자 정의 스트림 클래스
public async override Task <int> Read(byte[] buffer, int offset, int count)
을 그리고하지 않습니다 실제 서명과 일치하므로 컴파일 오류 메시지가 표시됩니다. 어떻게 든이 스트림 내에서 * Async를 사용하여 어떻게 풀 수 있었는지, 아니면 그냥 동기로 두어야합니까?
나는 또한 내 클래스가 http://www.syntaxwarriors.com/2013/stream-varbinary-data-to-and-from-mssql-using-csharp/에서 가장 아이디어를 SQL Server의에와 VARBINARY (최대) 필드에서 데이터의 스트리밍을 가능하게한다 https://blogs.msdn.microsoft.com/pfxteam/2011/01/15/asynclazyt/에서 스티븐 Toub의 AsyncLazy을 사용했다. 여기
은 (주석 비동기 비트) 코드의 흥미 비트이다 :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();
}
}
}
'대기'또는 '결과'를 호출하면 교착 상태가 발생할 수 있습니다. 비동기 버전을 래핑하여 동기 변형을 구현하지 마십시오. 동기 버전의 경우 동기식으로 진행하십시오. (그리고 비동기를위한 비동기) 비동기 메서드에 대해서는 동기 래퍼를 노출해야합니까? (https://blogs.msdn.microsoft.com/pfxteam/2012/04/13/should-i-expose-synchronous- wrappers-for-asynchronous-methods /) –
왜 비동기 메서드를 사용 하시겠습니까? –
db 클래스의 * Async() 메서드를 사용하려는 이유를 묻는다면 ... '가정'이라고 가정했습니다. 모든 IO 물건, 나는 가능한 한 언제나'await * Async()'를 사용하는 것이 좋다고 생각했다 ?? – Terry