[同时调用的C#异步方法应等待第一个操作完成

问题描述 投票:2回答:2

我有一个看起来像]的方法>

public async Task<OpenResult> openAsync()

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

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

用C#实现此目的的方法是什么

我有一个看起来像公共异步任务的方法openAsync()我想做的事情是,如果在执行过程中当前有对openAsync的调用,我想...

c# .net
2个回答
0
投票

通常],这类细节留给调用者,即通过适当地使调用者await成为对象,并且仅在它们应该

调用方法时才调用方法。但是,如果您must]执行此操作,则一种简单的方法是通过信号灯;考虑:

0
投票
尝试一下:

class MyClass { private Task<OpenResult> _currentOpenTask; public Task<OpenResult> QueuedOpenAsync() { return Interlocked.CompareExchange(ref _currentOpenTask, OpenAsyncAndUnlock(), null) ?? _currentOpenTask; } private async Task<OpenResult> OpenAsyncAndUnlock() { var result = await OpenAsync(); _ = Interlocked.CompareExchange(ref _currentOpenTask, null, _currentOpenTask); return result; } public async Task<OpenResult> OpenAsync() { await Task.Delay(5000); return new OpenResult(); } } class OpenResult { }

使用QueuedOpenAsync。如果OpenTask不为空,它将返回当前的_currentOpenTask,否则将创建一个并在一次执行原子操作中设置_currentOpenTask。当原始的OpenAsync方法完成时,则_currentOpenTask设置为null,因此所有操作都会重置-这就是OpenAsyncAndUnlock的目的。 Interlocked.CompareExchange是原子的,具有完整的内存屏障:https://docs.microsoft.com/en-us/dotnet/api/system.threading.interlocked.compareexchange?view=netframework-4.8
© www.soinside.com 2019 - 2024. All rights reserved.