异步写二进制?

Write binary asynchronously?

我正在尝试使旧方法异步。
它从数据库中获取 BLOB 并将其作为文件写入磁盘。

但是,BinaryWriter.
的写入方法没有异步版本 我可以改用 StreamWriter 吗?因为它有 WriteAsync 方法。 有什么区别?有什么缺点吗?

部分代码:

OracleParameter returnParam = new OracleParameter("blob", OracleDbType.Blob);
command.Parameters.Add(returnParam);

await command.ExecuteNonQueryAsync();

OracleBlob blob = returnParam.Value as OracleBlob;

byte[] data = new byte[blob.Length];

await blob.ReadAsync(data, 0, Convert.ToInt32(blob.Length));

fileFullPath = Path.Combine(folder, fileName);

using (FileStream fs = new FileStream(fileFullPath, FileMode.OpenOrCreate, FileAccess.Write))
{
    using (BinaryWriter bw = new BinaryWriter(fs))
    {
        bw.Write(data); //NO ASYNC METHOD HERE
        logger.Debug("Finished writing file {0} to disk", fileFullPath);
    }
}

我可以改成下面这样吗?

OracleParameter returnParam = new OracleParameter("blob", OracleDbType.Blob);
command.Parameters.Add(returnParam);

await command.ExecuteNonQueryAsync();

OracleBlob blob = returnParam.Value as OracleBlob;

byte[] data = new byte[blob.Length];

await blob.ReadAsync(data, 0, Convert.ToInt32(blob.Length));

fileFullPath = Path.Combine(folder, fileName);

using (FileStream fs = new FileStream(fileFullPath, FileMode.OpenOrCreate, FileAccess.Write))
{
    using (var writer = new StreamWriter(fs))
    {
        await writer.WriteAsync(new UnicodeEncoding().GetChars(data)); // HAD TO CONVERT THE BYTE ARRAY INTO A CHAR ARRAY
        logger.Debug("Finished writing file {0} to disk", fileFullPath);
    }
}

It takes the BLOB from the database and writes it to the disk as a file.

通常情况下,这应该是不必要的。如果您正在编写服务器,则可以通过 HTTP handler 或任何等效的方式将其分发。

如果这更像是一个下载操作,您需要最少的多任务处理量:

向它扔很多任务并没有帮助。这个操作听起来像是网络-(数据库)或磁盘绑定。您所能做的就是将整个 read/write 过程移动到一个单独的备用任务中。这样执行就不会占用 GUI。这是多任务处理的最低限度,即使是现在编写文字处理器也必须这样做。

这里还有有用的信息:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/#dont-block-await-instead

您可以将整个代码移动到一个异步函数中。 确保函数 returns 是一个任务,即使它是 one without result。然后你调用它,然后等待它。

这里不需要BinaryWriter。只是 WriteAsync byte[] 到流

using (FileStream fs = new FileStream(fileFullPath, FileMode.OpenOrCreate, FileAccess.Write))
{
   await fs.WriteAsync(data,0,data.Length);
   logger.Debug("Finished writing file {0} to disk", fileFullPath);
}