调用异步方法时,StreamWriter使用同步调用

Vtortola

我正在创建一个类似class的流,该流继承自Stream当我使用StreamWriter类异步编写信息时:

using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
    await sw.WriteAsync(msg);

我可以看到如何StreamWriter直接void Stream.Write(byte[] buffer, int offset, int count)而不是Task Stream.WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)

这是错误还是我错过了什么?

Vtortola

我发现了混乱的根源。

StreamWriter 默认情况下,同步刷新,除非您专门进行异步刷新。

Stream.Flush 在关闭(当然是冲洗)时被调用。

这将调用Write而不是WriteAsyncmessageWriter流中:

using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
    await sw.WriteAsync("Hi");

StreamWriter将缓冲“Hi”的消息,并且其将被释放到底层流上Flush关闭时同步地调用StreamWriter

因此,异步调用toStreamWriter.WriteAsync不会对基础流产生任何影响(因为有缓冲),并且在调用StreamWriter.CloseStreamWriter.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 
}

显然这也是:

using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
{
    await sw.WriteAsync("Hi"); 
    sw.Flush(); 
}

这将称为WriteAsync

using (var sw = new StreamWriter(messageWriter, Encoding.UTF8))
{
    await sw.WriteAsync("Hi");
    await sw.FlushAsync()
}

我创建了一个简单的类来跟踪方法的调用方式:

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(() => { });
    }
}

而这个测试:

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();
}

产量:

Simple
Write
Write

AutoFlush
Write
WriteAsync

Flush async
WriteAsync
WriteAsync

第一个是UTF8 BOM,第二个是实际数据。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

同步调用异步方法时出错

来自分类Dev

同步调用异步方法

来自分类Dev

异步调用同步方法

来自分类Dev

如何同步调用异步(等待)方法?

来自分类Dev

如何同步调用异步(等待)方法?

来自分类Dev

异步调用的同步循环

来自分类Dev

异步调用方法

来自分类Dev

使同步调用异步时如何返回TaskStatus?

来自分类Dev

同步异步发出的异步调用

来自分类Dev

从异步调用void同步方法-无法等待void

来自分类Dev

如何从石英计划作业中同步调用异步方法

来自分类Dev

如何从 C# 中的同步调用异步方法?

来自分类Dev

同步调用 webAPI 方法

来自分类Dev

同步功能内的异步调用

来自分类Dev

Scala将异步调用与Future同步

来自分类Dev

lua同步调用C异步函数

来自分类Dev

在内进行异步调用以同步

来自分类Dev

使科特林异步调用同步

来自分类Dev

lua同步调用C异步函数

来自分类Dev

在内进行异步调用以同步

来自分类Dev

同步CasperJS操作期间的异步调用

来自分类Dev

异步进程上的同步调用

来自分类Dev

异步调用WCF方法

来自分类Dev

异步调用WCF方法

来自分类Dev

同步调用异步函数时被调用者的线程会发生什么

来自分类Dev

异步调用同步方法比自然异步方法更快地完成任务

来自分类Dev

节点JS异步映射是同步或异步调用

来自分类Dev

使用Rhino从Java方法异步调用JavaScript回调

来自分类Dev

还需要同步调用支持时的C#异步