Blazor Server中Blazorise InputStream同步读取不支持问题排查
同步读取不支持错误排查:Blazorise IFileEntry/IBrowserFile 解密失败但加密正常
在使用Blazorise的IFileEntry(或标准Blazor上传的IBrowserFile)处理文件时,遇到以下矛盾问题:
- 解密方法中调用
inputStream.Read(buffer)抛出**"Synchronous reads are not supported"**错误 - 加密方法中完全相同的
inputStream.Read(buffer)逻辑却能正常运行
报错的解密代码
public static void FileDecrypt(IFileEntry file, string newFileName, string key) { FileStream fsCrypt = new(newFileName, FileMode.Create); byte[] iv = new byte[16]; using (Aes aes = Aes.Create()) { aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); byte[] buffer = new byte[MAX_BYTES]; int read; using Stream inputStream = file.OpenReadStream(); try { // 此处抛出“Synchronous reads are not supported”错误 while ((read = inputStream.Read(buffer)) > 0) { byte[] result = decryptor.TransformFinalBlock(buffer, 0, read); fsCrypt.Write(result, 0, read); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } } }
正常运行的加密代码
public static void FileEncrypt(IFileEntry file, string newFileName, string key) { FileStream fsCrypt = new(newFileName, FileMode.Create); byte[] iv = new byte[16]; using (Aes aes = Aes.Create()) { aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = iv; ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); byte[] buffer = new byte[MAX_BYTES]; int read; using CryptoStream cryptoStream = new CryptoStream((Stream)fsCrypt, encryptor, CryptoStreamMode.Write); using Stream inputStream = file.OpenReadStream(); try { // 此处读取正常 while ((read = inputStream.Read(buffer)) > 0) { cryptoStream.Write(buffer, 0, read); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } } }
问题原因
Blazor/WebAssembly环境下,浏览器提供的文件流(OpenReadStream()返回的实例)仅支持异步IO操作,不允许同步读取。
加密方法看似正常,实际是因为CryptoStream.Write内部会触发异步缓冲逻辑,间接让流的读取操作被异步处理,绕过了同步读取的限制;而解密方法中直接调用同步Read,触发了流的底层限制,导致报错。
你提到使用ReadAsync后无响应,通常是因为没有正确使用await,或者用.Result/.Wait()同步等待异步方法,导致Blazor的同步上下文死锁。
修复方案
将解密方法改为全异步实现,确保所有流操作都使用异步API,同时修正AES变换的错误用法:
public static async Task FileDecryptAsync(IFileEntry file, string newFileName, string key) { using var fsCrypt = new FileStream(newFileName, FileMode.Create); byte[] iv = new byte[16]; using Aes aes = Aes.Create(); aes.Key = Encoding.UTF8.GetBytes(key); aes.IV = iv; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); byte[] buffer = new byte[MAX_BYTES]; int read; using Stream inputStream = file.OpenReadStream(); try { // 使用异步读取,必须加await while ((read = await inputStream.ReadAsync(buffer)) > 0) { // 循环中用TransformBlock处理块数据,不能用TransformFinalBlock int bytesProcessed = decryptor.TransformBlock(buffer, 0, read, buffer, 0); await fsCrypt.WriteAsync(buffer, 0, bytesProcessed); } // 所有块处理完成后,调用TransformFinalBlock处理剩余数据 byte[] finalBytes = decryptor.TransformFinalBlock(Array.Empty<byte>(), 0, 0); if (finalBytes.Length > 0) { await fsCrypt.WriteAsync(finalBytes, 0, finalBytes.Length); } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } }
关键注意事项
- 所有异步流操作必须用
await调用,禁止用.Result/.Wait()同步等待,避免Blazor上下文死锁。 TransformFinalBlock只能在所有块数据处理完成后调用一次,循环中处理块数据必须用TransformBlock,否则会导致解密数据损坏。- 方法需声明为
async Task,调用方也要用await执行该方法。
内容的提问来源于stack exchange,提问作者Age of Empires
相关产品推荐
相关产品推荐

