You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

关键注意事项

  1. 所有异步流操作必须用await调用,禁止用.Result/.Wait()同步等待,避免Blazor上下文死锁。
  2. TransformFinalBlock只能在所有块数据处理完成后调用一次,循环中处理块数据必须用TransformBlock,否则会导致解密数据损坏。
  3. 方法需声明为async Task,调用方也要用await执行该方法。

内容的提问来源于stack exchange,提问作者Age of Empires

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:52:11