将 Async/Await 与一次性对象一起使用

作者 : 慕源网 本文共1937个字,预计阅读时间需要5分钟 发布时间: 2022-04-3 共326人阅读

本文将通过示例展示在使用 async/await 模式时如何处理一次性对象。使用 await 时,微软推荐使用ConfigureAwait方法,如下图,

await this._channel.Writer.WriteAsync(item, token).ConfigureAwait(false);

正如 Steven Toub 在这篇文章中解释的那样,使用 ConfigureAwait(false) 可以避免强制在原始上下文或调度程序上调用回调:ConfigureAwait FAQ – .NET Blog (microsoft.com)。这可以提高性能并避免死锁。但是使用 using 模式创建对象时有点棘手,因为 ConfigureAwait() 返回 ConfiguredAsyncDisposable。

强烈推荐

海量程序代码,编程资源,无论你是小白还是大神研究借鉴别人优秀的源码产品学习成熟的专业技术强势助力帮你提高技巧与技能。在此处获取,给你一个全面升级的机会。只有你更值钱,才能更赚钱

如果你是初级程序员可以研究别人的代码提高技术,如果你喜欢搞网盟或者外包,可以让你快速建站,还等什么赶快关注吧,我们会持续输出相关资源

海量源码程序,学习别人的产品设计思维与技术实践

如何实施

让我们在我的开源项目Spargine中更改一些代码。下面的代码将字符串转换为Brotli压缩字符串。

await using(var inputStream = new MemoryStream(Encoding.Unicode.GetBytes(input)))
{
    await using(var outputStream = new MemoryStream())
    {
        await using(var brotliStream = new BrotliStream(outputStream, level))
        {
            await inputStream.CopyToAsync(brotliStream).ConfigureAwait(false);
            await brotliStream.FlushAsync().ConfigureAwait(false);
            return Convert.ToBase64String(outputStream.ToArray());
        }
    }
}

当我在MemoryStream的创建中加入ConfigureAwait(false),会出现错误,

将 Async/Await 与一次性对象一起使用

出现错误是因为 inputStream 现在实际上是 ConfiguredAsyncDisposable 类型,因此 CopyToAsync() 不可用。为了解决这个问题,我们需要在 using 语句之前创建一次性类型,如下所示,

var inputStream = new MemoryStream(Encoding.Unicode.GetBytes(input));

await using(inputStream.ConfigureAwait(false))
{
    var outputStream = new MemoryStream();

    await using(outputStream.ConfigureAwait(false))
    {
        var brotliStream = new BrotliStream(outputStream, level);

        await using(brotliStream.ConfigureAwait(false))
        {
            await inputStream.CopyToAsync(brotliStream).ConfigureAwait(false);
            await brotliStream.FlushAsync().ConfigureAwait(false);
            return Convert.ToBase64String(outputStream.ToArray());
        }
    }
}

不幸的是,此代码将导致以下错误,

CA2000: Call System.IDisposable.Dispose on object created by ‘new MemoryStream()’ before all references to it are out of scope

要修复它,请将此属性添加到方法中,

[SuppressMessage(“Microsoft.Build”, “CS2000”)]

我确实希望微软在我们没有进行这么多代码更改的情况下解决了这个问题。

概括

隐藏的处置问题更难解决,比如这个。我强烈建议将IDisposableAnalyzers NuGet 包添加到您的所有项目中,以发现此类一次性问题。我相信这应该是 .NET 的一部分,而不是必须添加的包,因为如果您的代码库有虚拟内存问题,我可以说大多数项目都有!

有什么评价或者疑问吗?请在下面制作。


慕源网 » 将 Async/Await 与一次性对象一起使用

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录