c# - 是否有与 StreamReader 的 Peek 方法等效的异步方法?

标签 c# asynchronous .net-core stream streamreader

我正在更新一些netstandard2.0不从 HttpRequest.Body 读取代码(a Stream )同步(这会在 netcoreapp3.0 中引发异常,除非您设置 AllowSynchronousIO 选项,这显然不是一个好主意)。

我已经转换了 JSON 反序列化部分(以使用 System.Text.Json ),但在此之前它会偷偷摸摸地执行 .Peek() 。使用StreamReader (看看主体是对象还是数组),我不确定在哪里寻找异步且不会消耗 Stream 的现代替代方案.

using var reader = new StreamReader(stream);
switch (reader.Peek()) // TODO: Find an async equivalent!
{
    case '{':
        return await JsonSerializer.DeserializeAsync<GraphQLRequest>(stream);
    case '[':
        return await JsonSerializer.DeserializeAsync<GraphQLRequest[]>(stream);
    default:
        // ...
}

最佳答案

实际上,Peek 方法首先将流读入其缓冲区,然后为您提供其中的值(看看 dotnet runtime repo )。所以它移动了流的位置。但是,如果不读取并寻找流,则无法实现查看功能。

由于您无法返回 HttpRequestStream,因此更好的策略是读取整个内容,然后使用 Utf8JsonReader 来确定请求是对象还是数组。请注意,Utf8JsonReader 无法在异步方法中声明,因此我必须将其放在单独的非异步方法中。

private static JsonTokenType GetTokenType(byte[] bytes)
{
    var reader = new Utf8JsonReader(bytes.AsSpan());
    reader.Read();
    return reader.TokenType;
}
var ms = new MemoryStream();
await Request.Body.CopyToAsync(ms);
var jsonBytes = ms.ToArray();

switch (GetTokenType(jsonBytes)) 
{
    case JsonTokenType.StartObject:
        return JsonSerializer.Deserialize<GraphQLRequest>(jsonBytes);
    case JsonTokenType.StartArray:
        return JsonSerializer.Deserialize<GraphQLRequest[]>(jsonBytes);
    default:
        // ...
}

关于c# - 是否有与 StreamReader 的 Peek 方法等效的异步方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616855/

相关文章:

c# - 如何以编程方式登录网站进行屏幕显示?

c# - 如何使用 ODP.Net 传递字节数组?

c# - 使用 Sears API 的 Web 请求

javascript - 为什么我的 indexedDB.open.onsuccess 事件没有被调用?

java - 如何使用 Mockito 在 Spring Boot 中模拟异步(@Async)方法?

c# - 如何在我的业务逻辑层中管理统一性?

c# - 在 C# 项目中部署 CasperJS

c# - 哪个异步调用用于数据库连接和仍然响应的 GUI?--

c# - .NET Core 性能计数器的故事是什么?

c# - 是否可以在针对 4.7.1 的 WinForms 项目中使用 Path.GetRelativePath (.NET Core2)?