将Web应用程序从dotnet core 2.2升级到3.0时遇到了一个奇怪的问题。我遵循了migration steps中的适用步骤。
我的一个API调用返回HTTP500。更深入的调查表明,在UploadObjectAsync
上调用Google.Cloud.Storage.V1.StorageClient
会给我以下错误:
Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead
我可以使用以下代码片段快速修复此问题(但我不希望将此作为最终解决方案)。
WebHost.CreateDefaultBuilder(args)
.ConfigureKestrel(options => { })
.ConfigureServices(services =>
{
services.Configure<IISServerOptions>(options => { options.AllowSynchronousIO = true; });
})
失败的API正在处理分段上传到Google存储空间的问题。我将问题缩小到MultipartSection或更优的MultipartSection.Body属性,该属性从程序集MultipartReaderStream
(v3.0.0.0)返回内部类Microsoft.AspNetCore.WebUtilities
。
MultipartReaderStream
中的内容不符合要求。暂时将MultipartSection.Body
换成简单的磁盘文件(例如File.Open(@"c:\file")
)可以正常工作。这使我相信问题不在于Google的StorageClient
,而在于MultipartReaderStream
。现在,在我得到建议将整个流读入MemoryStream
并上传到Google Storage之前,我只想说我正在处理的是大文件,最好不要缓冲。
看MultipartReaderStream source,发现同步_innerStream.Read()
多次出现。这可能引起问题吗?即使在MultipartReaderStream v3.1中也是如此。
[编辑]
进一步深入研究后,发现可能根本不是MultipartReaderStream
的错误。通过进一步的实验,我得出的结论是,问题可能出在Google的实现中(或什至两者都有)。如果我抛出自己的Stream
实现并在Read
处设置断点,则会从Google代码中触发。类ResumableUpload似乎也使用同步读取。最著名的是PrepareNextChunkUnknownSize
方法不是异步的,它使用同步读取。