并发调用的 C# 异步方法应等待第一个操作完成

标签 c# .net

我有一个看起来像的方法

public async Task<OpenResult> openAsync()

我想做一些事情,比如如果在执行过程中当前有对 openAsync 的调用,我想将对 OpenAsync 的任何调用添加到队列中。

当第一个调用完成时,我想用第一个调用的结果完成队列中的所有。

在C#中有什么方法可以实现

最佳答案

通常,这种细节留给调用者,即通过让调用者适本地await并且只在它们应该时调用方法调用方法。但是,如果您必须这样做,一种简单的方法是通过信号量;考虑:

class HazProtected
{
    private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

    public async Task<OpenResult> OpenAsync(CancellationToken cancellationToken = default)
    {
        await _lock.WaitAsync(cancellationToken);
        try
        {
            return await DoOpenAsync(cancellationToken);
        }
        finally
        {
            _lock.Release();
        }
    }

    private async Task<OpenResult> DoOpenAsync(CancellationToken cancellationToken)
    {
        // ... your real code here
    }
}

OpenAsync 中的代码确保一次只能有一个并发异步调用者尝试打开它。当发生冲突时,调用者将被异步保留,直到可以获取信号量。但是,有一个复杂的问题; SempahoreSlim 在 .NET Framework 上存在一些已知问题(已在 .NET Core 中解决)同时存在异步 同步信号量获取 - which can lead to a spiral of death .


在更复杂的场景中,可以编写自己的待处理调用者队列;这是一个非常非常奇特的场景,通常不应该尝试,除非您确切地理解为什么要这样做!

关于并发调用的 C# 异步方法应等待第一个操作完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60168262/

相关文章:

c# - 释放互斥锁

c# - C/C++/C#: how to force repaint of window chrome on windows 7?

c# - 为什么公共(public)语言运行库不能支持 Java

.net - 获取英语异常消息而不是本地语言

c# - 给定 UserPrincipal 对象,如何从 Active Directory 获取 "Company"和 "Department"?

c# - 如何重用 where 条件

c# - 将 sbyte[,] 存储到磁盘并返回的最佳方法是什么

c# - 对一系列值执行操作的 C# 模式是什么?

c# - 如何将锯齿状数组绑定(bind)到 DataGridView 中?

c# - WCF 服务 - 支持范围为 : bytes support? 的流式文件