2

我的.NET Core 3.1项目中有这个格式化程序(我最近从 升级2.1):

public class JilOutputFormatter : TextOutputFormatter {


    public JilOutputFormatter() => 
        JilFormatterConfig.AddSupportedHeaders(SupportedMediaTypes, SupportedEncodings);

    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) {
        using (var writer = new StreamWriter(context.HttpContext.Response.Body)) {
            JSON.Serialize(context.Object, writer, MyOptions);
            writer.Flush();
        }

        return Task.FromResult(true);
    }

}

我用这个片段将它添加到管道中:

services.AddMvcCore(o => {
    o.OutputFormatters.Insert(0, new JilOutputFormatter());
}).AddOthersBlahBlah();

当应用程序打开时,它就像一个魅力2.1。但是现在3.1我收到了这个错误:

处理请求时发生未处理的异常。InvalidOperationException:不允许同步操作。改为调用 WriteAsync 或将 AllowSynchronousIO 设置为 true。

我尝试异步写入操作,但在Jil. 请问你有什么想法吗?

注意:我知道有一些答案(例如这个答案)是在说如何AllowSynchronousIO. 但我对如何异步写入感兴趣Jil

4

3 回答 3

2

您必须使用 3.0 alpha 版本。Jil甚至没有Task在最新的稳定版本 2.17 的源代码中包含这个词(或者 Github 搜索有一些问题)。

3.0 版直接使用管道。您可以使用SerializeAsync(T, PipeWriter , Encoding, Options, CancellationToken)也许您可以使用 HttpContext.Response.BodyWriter。我还没有测试过这个。

例如:

public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context,
                                                  Encoding selectedEncoding) 
{
    var data=context.Object;
    var writer=contest.Response.BodyWriter;
    await JSON.SerializeAsync(data,writer,selectedEncoding);
}
于 2019-12-16T11:25:10.060 回答
1

错误可能围绕ReadAsyncWriteAsyncFlushAsync,输出类似于下面列出的内容。

Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.

Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.

Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.

作为临时解决方法,您可以在类中找到的方法中AllowSynchronousIO设置的值。ConfigureServicesStartup

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<KestrelServerOptions>(options =>
    {
        options.AllowSynchronousIO = true;
    });

    // If using IIS:
    services.Configure<IISServerOptions>(options =>
    {
        options.AllowSynchronousIO = true;
    });

    // other services
}

这不是一个很好的解决方法,但它会让你继续前进。更好的解决方案是升级您的库并异步执行所有操作。

请参阅Khalid Abuhakmeh的详细帖子.NET Core 3.0 AllowSynchronousIO Workaround

于 2020-01-30T12:47:16.990 回答
0

TLDR:从 Dotnet Core 5.0 开始,默认的 Web 服务器 (Kestral) 旨在仅执行异步级别的工作以达到最高性能。在 Kestral 中启用同步。

理性:由于大多数软件比 CPU 更依赖 IO,异步编程允许系统执行其他工作,同时等待 IO 完成(IE;写入磁盘,从网络读取某些内容)。

将其放在 ConfigurationService 函数中的 Startup.cs 中。

   services.Configure<KestrelServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });
于 2022-02-27T19:21:37.397 回答