1 回答

TA貢獻(xiàn)1712條經(jīng)驗(yàn) 獲得超3個(gè)贊
使用選項(xiàng) 1,您將向源發(fā)出許多請(qǐng)求以獲取數(shù)據(jù),并且GetBytes
不會(huì)在 SQL 服務(wù)器上“搜索”流(如果確實(shí)如此,我會(huì)感到驚訝),這將是一個(gè)非常低效的解決方案。
IAsyncEnumerable
使用選項(xiàng) 2,您可以獲得流并按需處理它,因此您將發(fā)出單個(gè)數(shù)據(jù)庫(kù)請(qǐng)求,并獲得異步 I/O 的所有好處。
使用C# 8
?IAsyncEnumerablePreview
將完美地解決您的問(wèn)題,但到目前為止它還處于階段。
復(fù)制到異步
如果您可以獲得需要將內(nèi)容上傳到的流,那么您可以使用CopyToAsync。但我假設(shè)每個(gè)塊都將在單獨(dú)的請(qǐng)求中上傳。如果是這樣,您可以引入一個(gè)組件,它會(huì)像 a 一樣發(fā)出嘎嘎聲,但當(dāng)數(shù)據(jù)庫(kù)流在其上調(diào)用 CopyToAsync()Stream
時(shí),它實(shí)際上會(huì)將內(nèi)容上傳到網(wǎng)站:
class WebSiteChunkUploader : Stream
{
? ? ?private HttpClient _client = new HttpClient();
? ? ?public override bool CanWrite => true;
? ? ?public override bool CanRead => false;
? ? ?public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
? ? ? ? ?await _client.PostAsync("localhost", new ByteArrayContent(buffer,offset, count));
}
老好 IEnumerable
不幸的是你不能與yield return混合。但是,如果您決定使用阻塞 api 讀取流,例如,那么您可以使用舊的 good 重寫(xiě)它:IEnumerableasync/awaitReadyield return
public IEnumerable<Tuple<byte[],int>> TransferDocument(int documentId, int maxChunkSize)
{
? ? string sql = "SELECT Data FROM Document WHERE Id = @Id";
? ? var buffer = new byte[maxChunkSize];
? ? using (SqlConnection connection = new SqlConnection(ConnectionString))
? ? {
? ? ? ? connection.Open();
? ? ? ? using (SqlCommand command = new SqlCommand(sql, connection))
? ? ? ? {
? ? ? ? ? ? command.Parameters.AddWithValue("@Id", documentId);
? ? ? ? ? ? using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
? ? ? ? ? ? using (Stream uploadDataStream = reader.GetStream(0))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? while(var bytesRead = uploadDataStream.Read(buffer, 0, maxChunkSize)) > 0)
? ? ? ? ? ? ? ? ? ?yield return Tuple(buffer, bytesRead);
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
...
async Task DoMyTransfer()?
{
? foreach(var buffer in TransferDocument(1, 10000)) {
? ? await moveBytes(buffer)
? }
}
在這種情況下,您不會(huì)與 DB 和 fancy 進(jìn)行異步 IO Tasks,但我想您無(wú)論如何都需要限制此上傳操作,以免連接導(dǎo)致數(shù)據(jù)庫(kù)過(guò)載。
- 1 回答
- 0 關(guān)注
- 139 瀏覽
添加回答
舉報(bào)