ReSharper建议将Using语句转换为单个"await Using"吗?

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

在应用连续的 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;
        }
    }

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

2
这只是C# 8中引入的一种语法糖。 - DetectivePikachu
1
“await using” 适用于任何实现“IAsyncDisposable”的内容,这样可以拥有异步处理方法。 - juharr
@Çöđěxěŕ 你是正确的,这是使用异步可处置对象,在C# 8中引入的。 - DetectivePikachu
@DetectivePikachu 当然是这样,但它们是两个不同的东西。第一个不会异步释放资源,而第二个当然会,并且对于 OP 来说更好;它使消费者能够在不阻塞主线程的情况下处理操作。 - Trevor
我说你是对的,兄弟,你还需要什么? - DetectivePikachu
2个回答

15
当您接受该建议时,有两个变化:
  1. await using,您可以在实现新的IAsyncDisposable类型的情况下使用它。它与常规的using相同,只是调用DisposeAsync()而不是Dispose()

  2. using块到语句的更改。此建议仅旨在最小化代码中的嵌套。一旦对象超出范围,就会调用Dispose()/DisposeAsync()。您可以在文档中了解更多信息。

这些是您可以独立使用的两个单独的特性(您可以在块中使用await using,或将using用作语句),但两者都是该语言的全新功能。

谢谢你的回答,我们在什么情况下更喜欢其中之一? - RedRose
3
尽可能使用await using(并非总是可行 - 这取决于对象是否为IDisposableIAsyncDisposable)来理解异步编程的好处,您可以在此处阅读文档。using语句与块实际上只是个人偏好。当您想要控制对象的范围时,可能更喜欢块。 - Gabriel Luci
谢谢Gabriel Luci! - RedRose

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接