Resharper 建议将 Using 语句转换为单个“等待使用”?

Red*_*ose 3 resharper using async-await c#-8.0

Resharper 建议将带有 await 关键字的 using 语句改进为单行 await using 语句。例如,以下代码片段:

    private async Task<string> ReadResponseAsync(HttpContext context)
    {
        var originalBody = context.Response.Body;

        try
        {
            using (var responseStream = new MemoryStream())
            {
                context.Response.Body = responseStream;
                await _next(context).ConfigureAwait(false);

                var response = context.Response;
                response.Body.Seek(0, SeekOrigin.Begin);

                using (var responseReader = new StreamReader(response.Body))
                { 
                    var responseContent = await responseReader
                    .ReadToEndAsync()
                    .ConfigureAwait(false);

                    response.Body.Seek(0, SeekOrigin.Begin);

                    await responseStream.CopyToAsync(originalBody)
                    .ConfigureAwait(false);
                    return responseContent;
                }
            }
        }
        finally
        {
            context.Response.Body = originalBody;
        }
    }
Run Code Online (Sandbox Code Playgroud)

应用连续的 Resharper 建议后,代码变为以下内容:

    private async Task<string> ReadResponseAsync(HttpContext context)
    {

        var originalBody = context.Response.Body;

        try
        {
            await using var responseStream = new MemoryStream();
            context.Response.Body = responseStream;
            await _next(context).ConfigureAwait(false);

            var response = context.Response;
            response.Body.Seek(0, SeekOrigin.Begin);

            using var responseReader = new StreamReader(response.Body);
            var responseContent = await responseReader
                .ReadToEndAsync()
                .ConfigureAwait(false);

            response.Body.Seek(0, SeekOrigin.Begin);

            await responseStream.CopyToAsync(originalBody)
                .ConfigureAwait(false);
            return responseContent;
        }
        finally
        {
            context.Response.Body = originalBody;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这两个代码片段相似吗?这里实际上正在改进什么?我不理解 C# 使用语句的这个特性。

Gab*_*uci 10

当您接受该建议时,两件事发生了变化:

  1. await using,您可以在实现新的IAsyncDisposable. 它与常规 相同using,除了它调用DisposeAsync()而不是Dispose().

  2. 从一个using块到一个语句的变化。此建议只是为了尽量减少代码中的嵌套。一旦对象超出范围,则调用Dispose()/ DisposeAsync()。您可以在文档中阅读更多相关信息。

这是两个独立的功能,您可以彼此独立使用(您可以await using与块一起使用,或using用作语句),但两者都是该语言中的全新功能。

  • 尽可能使用“await using”(不能总是使用 - 这取决于对象是“IDisposable”还是“IAsyncDisposable”)。要了解异步编程的好处,您可以阅读此处的文档(https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/)。“using”语句与块实际上只是偏好。当您想要控制对象的范围时,您可能更喜欢使用块。 (2认同)