vto*_*ola 3 .net streamwriter async-await
我正在创建一个类继承自的类Stream.当我使用StreamWriter类异步写入信息时:
using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
await sw.WriteAsync(msg);
Run Code Online (Sandbox Code Playgroud)
我可以看到如何StreamWriter直接void Stream.Write(byte[] buffer, int offset, int count)而不是Task Stream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken).
这是一个错误还是我错过了什么?
我发现了混乱的根源.
StreamWriter 默认情况下会同步刷新,除非您专门异步刷新.
Stream.Flush 关闭时调用,当然还有冲洗.
这将调用Write而不是WriteAsync在messageWriter流中:
using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
await sw.WriteAsync("Hi");
Run Code Online (Sandbox Code Playgroud)
在StreamWriter将缓冲"Hi"的消息,并且其将被释放到底层流上Flush关闭时同步地调用StreamWriter.
因此,异步调用StreamWriter.WriteAsync可能对底层流没有影响(因为缓冲),并且在调用时StreamWriter.Close,StreamWriter.Flush会同步调用,因此Flush在底层流上调用方法.
此代码也Write同步调用:
using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
{
sw.AutoFlush = true; // will call Write here to send the UTF8 BOM
await sw.WriteAsync("Hi"); // Write the actual data
}
Run Code Online (Sandbox Code Playgroud)
显然这也是这个:
using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
{
await sw.WriteAsync("Hi");
sw.Flush();
}
Run Code Online (Sandbox Code Playgroud)
这会打电话WriteAsync:
using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
{
await sw.WriteAsync("Hi");
await sw.FlushAsync()
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个简单的类来跟踪方法的调用方式:
public class MSWrite : MemoryStream
{
public override bool CanWrite { get { return true; } }
public override void Write(byte[] buffer, int offset, int count)
{
Console.WriteLine("Write");
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
Console.WriteLine("WriteAsync");
return Task.Run(() => { });
}
}
Run Code Online (Sandbox Code Playgroud)
而这个测试:
Console.WriteLine("Simple");
using(var ms = new MSWrite())
using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
{
await sw.WriteAsync("Hi");
}
Console.WriteLine();
Console.WriteLine("AutoFlush");
using (var ms = new MSWrite())
using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
{
sw.AutoFlush = true;
await sw.WriteAsync("Hi");
}
Console.WriteLine();
Console.WriteLine("Flush async");
using (var ms = new MSWrite())
using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
{
await sw.WriteAsync("Hi");
await sw.FlushAsync();
}
Run Code Online (Sandbox Code Playgroud)
产量:
Simple
Write
Write
AutoFlush
Write
WriteAsync
Flush async
WriteAsync
WriteAsync
Run Code Online (Sandbox Code Playgroud)
第一个写入是UTF8 BOM,第二个是实际数据.
| 归档时间: |
|
| 查看次数: |
3645 次 |
| 最近记录: |