ASP.NET Core + StreamWriter:为什么 `await using` 的行为与 `using` 不同?
ASP.NET Core + StreamWriter: Why does `await using` behave differently than `using`?
我正在尝试在 ASP.NET Core 6 控制器方法中直接写入 Response.Body
,因为这在某些情况下性能更高。
为什么 await using
和 using
在下面的代码中表现不同?
[Route("api/[Controller]/[Action]")]
public class TestController : ControllerBase
{
[HttpGet]
[Produces("text/plain")]
public async Task GetPlainText()
{
// No `using`: it works
// Add `using` to the following line and the response will be empty
// Add `await using` to the following line and it will work
var sw = new StreamWriter(Response.Body, leaveOpen: true);
await sw.WriteAsync("Some normal text");
await sw.FlushAsync();
}
}
编辑
using var sw = new StreamWriter(...)
是否有效似乎取决于所使用的 HTTP 客户端。如果使用Chrome,控制台会报错,不显示任何文字。如果使用 Postman,则没有错误,并且响应包含“Some normal text”。
不是 100% 确定,但我会说这是因为流是在方法完成之后但在写入和刷新流的任务之前被释放的,实际上 运行 因为返回的只是承诺做那些事情。
它在没有 using
的情况下工作的原因是因为从未调用过 dispose。
它与 await using
一起工作的原因是因为流的处理也作为任务的一部分包含在内。
至于为什么客户端会有所不同,可能是因为它流式传输到一个并直接执行到另一个。
我真的应该查看 ASP.NET Core 的控制台输出,其中包含以下堆栈跟踪:
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.Flush()
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
所以问题是StreamWriter.Dispose
同步刷新底层流,默认不允许同步写操作。
我正在尝试在 ASP.NET Core 6 控制器方法中直接写入 Response.Body
,因为这在某些情况下性能更高。
为什么 await using
和 using
在下面的代码中表现不同?
[Route("api/[Controller]/[Action]")]
public class TestController : ControllerBase
{
[HttpGet]
[Produces("text/plain")]
public async Task GetPlainText()
{
// No `using`: it works
// Add `using` to the following line and the response will be empty
// Add `await using` to the following line and it will work
var sw = new StreamWriter(Response.Body, leaveOpen: true);
await sw.WriteAsync("Some normal text");
await sw.FlushAsync();
}
}
编辑
using var sw = new StreamWriter(...)
是否有效似乎取决于所使用的 HTTP 客户端。如果使用Chrome,控制台会报错,不显示任何文字。如果使用 Postman,则没有错误,并且响应包含“Some normal text”。
不是 100% 确定,但我会说这是因为流是在方法完成之后但在写入和刷新流的任务之前被释放的,实际上 运行 因为返回的只是承诺做那些事情。
它在没有 using
的情况下工作的原因是因为从未调用过 dispose。
它与 await using
一起工作的原因是因为流的处理也作为任务的一部分包含在内。
至于为什么客户端会有所不同,可能是因为它流式传输到一个并直接执行到另一个。
我真的应该查看 ASP.NET Core 的控制台输出,其中包含以下堆栈跟踪:
System.InvalidOperationException: Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.Flush()
at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder)
at System.IO.StreamWriter.Dispose(Boolean disposing)
at System.IO.TextWriter.Dispose()
所以问题是StreamWriter.Dispose
同步刷新底层流,默认不允许同步写操作。