C# ASP.NET Core 3.0中不允许缓冲流同步操作

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

我有一个针对aspnetcore2.2的restapi,其端点允许下载一些大的json文件。迁移到AspNetCore 3.1后,此代码停止工作:

    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 return
return文件(byteFile,“application/json”,enableRangeProcessing:true)
启用范围处理
帮助客户端恢复文件下载。