C# 来自MultipartSection的MultipartReaderStream:不允许同步操作。调用ReadAsync或将AllowSynchronousIO改为true

C# 来自MultipartSection的MultipartReaderStream:不允许同步操作。调用ReadAsync或将AllowSynchronousIO改为true,c#,google-api-dotnet-client,.net-core-3.0,asp.net-core-3.0,C#,Google Api Dotnet Client,.net Core 3.0,Asp.net Core 3.0,我从dotnet core 2.2升级到3.0时遇到了一个奇怪的问题。我已遵循了中的适用步骤 我的一个API调用返回HTTP 500。更深入的调查显示,在Google.Cloud.Storage.V1.StorageClient上调用UploadObjectAsync会产生以下错误: Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead 我可以使用下面的代码

我从dotnet core 2.2升级到3.0时遇到了一个奇怪的问题。我已遵循了中的适用步骤

我的一个API调用返回HTTP 500。更深入的调查显示,在
Google.Cloud.Storage.V1.StorageClient
上调用
UploadObjectAsync
会产生以下错误:

Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead
我可以使用下面的代码片段快速修复这个问题(但我不想将此作为最终解决方案)

WebHost.CreateDefaultBuilder(args)
.ConfigureKestrel(选项=>{})
.ConfigureServices(服务=>
{
Configure(options=>{options.AllowSynchronousIO=true;});
})
失败的API正在处理多部分上传到Google存储的问题。我已经将问题缩小到了一个属性,该属性从汇编
Microsoft.AspNetCore.WebUtilities
(v3.0.0.0)返回一个内部类
MultipartReaderStream

MultipartReaderStream
中的某些内容不符合要求。暂时将
MultipartSection.Body
替换为一个简单的磁盘文件(例如
file.Open(@“c:\file”)
)可以正常工作。这让我相信问题不在于谷歌的
StorageClient
,而在于
MultipartReaderStream
。现在,在我得到在上传到Google Storage之前将整个流读取到
MemoryStream
的建议之前,让我先说一下,我处理的是最好不要缓冲的大型文件

查看后发现,同步
\u innerStream.Read()
多次出现。这会导致问题吗?即使在欧洲,也存在同样的情况

[编辑]


经过更深入的研究,最终发现这可能不是
MultipartReaderStream
的错误。进一步的实验让我得出结论,这个问题可能在谷歌的实现中(或者两者兼而有之)。如果我加入自己的
实现,并在
读取
处设置一个断点,我会从谷歌代码中被触发。该类似乎也使用同步读取。最值得注意的是,
PrepareNextChunkUnknownSize
方法不是异步的,并且使用同步读取。

即使在2.2版中,这也是一个“问题”,但3.0将不允许同步I/O作为默认设置。在github/AspNetCore上的各种问题中都提到了对多部分内容的真正异步处理的支持,并且似乎被跟踪(间接地,作为移动到管道的一部分)。由于同步I/O在默认情况下被禁用,这些剩余的同步延迟可能会更快地被识别和修复,但我们还没有做到这一点。那么有没有一种解决方法不涉及一次读取整个流?我在把它传下去之前,刚刚试着阅读来记忆它,它起了作用,但这离理想还很远。是否有任何第三方库可以执行
MultipartReader
的工作?有两种明显的解决方法:要么放下手头的工作,将同步I/O所涉及的所有代码重写为异步(向您供电,发出请求),要么。。。现在只需将
AllowSynchronousIO
设置为
true
,然后继续。禁止同步I/O是为了可能提高性能并减少死锁的可能性。在第三方库中使用同步I/O,而在预缓冲所有内容的情况下,可以证明代码的性能要差得多,如果用不太理想的代码进行交易,那将是荒谬的。同步I/O不是死刑。问题肯定出在
Google.api
assembly中。我创建了一个补丁。公关部接受。正在等待项目所有者发布NuGet更新。我欢迎您@Jeroemostert给出答案。我很高兴感谢你帮我度过了难关。当你投入实际的侦查工作,甚至构建了一个实际的修复方案时,你的答案比我的更有价值,因为你最终解决了自己的问题。我会在任何一天接管虚拟积分。
        WebHost.CreateDefaultBuilder(args)
            .ConfigureKestrel(options => { })
            .ConfigureServices(services =>
            {
                services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
            })