C# ASP.NET Core 3.0中不允许缓冲流同步操作
我有一个针对aspnetcore2.2的restapi,其端点允许下载一些大的json文件。迁移到AspNetCore 3.1后,此代码停止工作:C# ASP.NET Core 3.0中不允许缓冲流同步操作,c#,asp.net-core,asynchronous,core,asp.net-core-3.1,C#,Asp.net Core,Asynchronous,Core,Asp.net Core 3.1,我有一个针对aspnetcore2.2的restapi,其端点允许下载一些大的json文件。迁移到AspNetCore 3.1后,此代码停止工作: try { HttpContext.Response.StatusCode = (int)HttpStatusCode.OK; HttpContext.Response.Headers.Add("Content-Type", "application/json"); using (va
try
{
HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
HttpContext.Response.Headers.Add("Content-Type", "application/json");
using (var bufferedOutput = new BufferedStream(HttpContext.Response.Body, bufferSize: 4 * 1024 * 1024))
{
await _downloadService.Download(_applicationId, bufferedOutput);
}
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
}
这是下载方法,它创建了我想在HttpContext.Response.Body上返回的json:
public async Task Download(string applicationId, Stream output, CancellationToken cancellationToken = default(CancellationToken))
{
using (var textWriter = new StreamWriter(output, Constants.Utf8))
{
using (var jsonWriter = new JsonTextWriter(textWriter))
{
jsonWriter.Formatting = Formatting.None;
await jsonWriter.WriteStartArrayAsync(cancellationToken);
//write json...
await jsonWriter.WritePropertyNameAsync("Status", cancellationToken);
await jsonWriter.WriteValueAsync(someStatus, cancellationToken);
await jsonWriter.WriteEndArrayAsync(cancellationToken);
}
}
}
现在我得到了一个例外:“ASP.NET Core 3.0中不允许同步操作”
如何在不使用AllowSynchronousIO=true的情况下更改此代码以使其工作
AllowSynchronousIO
选项在(Kestrel
,HttpSys
,IIS进程中
,TestServer
)中的.Net core 3.0.0-preview3
中默认禁用,因为这些API是线程不足和应用程序挂起的根源
对于临时迁移的每个请求,可以覆盖该选项:
var allowSynchronousIoOption = HttpContext.Features.Get<IHttpBodyControlFeature>();
if (allowSynchronousIoOption != null)
{
allowSynchronousIoOption.AllowSynchronousIO = true;
}
var allowSynchronousIoOption=HttpContext.Features.Get();
if(allowSynchronousIoOption!=null)
{
AllowSynchronousIO选项。AllowSynchronousIO=true;
}
您可以找到更多信息并遵循ASP.NET核心问题跟踪程序:通过在退出using子句之前调用FlushAsync和DisposeAsync,您可以停止编写器部署期间发生的同步操作。BufferedStream似乎存在同步写入问题,如何控制StreamWriter中的缓冲区大小
using (var streamWriter = new StreamWriter(context.Response.Body, Encoding.UTF8, 1024))
using (var jsonWriter = new JsonTextWriter(streamWriter))
{
jsonWriter.Formatting = Formatting.None;
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("test");
await jsonWriter.WriteValueAsync("value " + new string('a', 1024 * 65));
await jsonWriter.WriteEndObjectAsync();
await jsonWriter.FlushAsync();
await streamWriter.FlushAsync();
await streamWriter.DisposeAsync();
}
通过这种方式,您可以在不进行
AllowSynchronousIO=true
的情况下对代码进行少量更改,从而使代码正常工作。这可能是在使用块结束之前需要FlushAsync的流之一吗?这是隐藏的原因之一,因为using语句调用Dispose(),这不是异步的。C#8确实为支持IAsyncDIsposable的对象提供了异步使用版本。是的,这是我在需要它的端点上使用的版本,但我想看看我是否可以在没有它的情况下进行管理;替换为BufferedReadStream或其他东西just returnreturn文件(byteFile,“application/json”,enableRangeProcessing:true)
,启用范围处理
帮助客户端恢复文件下载。