MultipartReaderStream from MultipartSection: синхронные операции запрещены. Вместо этого вызовите ReadAsync или установите для параметра AllowSynchronousIO значение true. - PullRequest
0 голосов
/ 23 октября 2019

Я столкнулся со странной проблемой при обновлении моего веб-приложения с dotnet core 2.2 до 3.0. Я выполнил соответствующие шаги из шагов миграции .

Один из моих вызовов API возвращает HTTP 500. Более глубокое исследование показывает, что вызов 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 Storage. Я сузил проблему до MultipartSection или еще лучше MultipartSection.Body свойство, которое возвращает внутренний класс MultipartReaderStream из сборки Microsoft.AspNetCore.WebUtilities (v3.0.0.0).

Что-то в MultipartReaderStream не соответствует. Временная замена MultipartSection.Body для простого файла на диске (например, File.Open(@"c:\file")) работает нормально. Это наводит меня на мысль, что проблема не в StorageClient Google, а в MultipartReaderStream. Теперь, прежде чем я получу предложения прочитать весь поток в MemoryStream перед загрузкой в ​​Google Storage, позвольте мне сказать, что я имею дело с огромными файлами, которые лучше не буферизировать.

Просмотр источника MultipartReaderStream Оказывается, есть несколько случаев синхронного _innerStream.Read(). Может ли это быть причиной проблемы? То же самое присутствует даже в MultipartReaderStream v3.1 .

[EDIT]

После копания еще глубже выясняется, что это может быть не ошибка MultipartReaderStream после всего. Эксперименты привели меня к выводу, что проблема может быть в реализации Google (или даже в обоих). Если я добавлю свою собственную реализацию Stream и установлю точку останова на Read, меня вызовет код Google. Класс ResumableUpload , кажется, также использует синхронные чтения. В частности, метод PrepareNextChunkUnknownSize НЕ является асинхронным и использует синхронное чтение.

...