c# async和await用法及disposable虚拟内存问题

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

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

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

使用 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),会出现错误,

c# async和await用法及disposable虚拟内存问题

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

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 包添加到您的项目中,以解决此类Disposable问题。


慕源网 » c# async和await用法及disposable虚拟内存问题

常见问题FAQ

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

发表评论

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