我有一个异步方法,有时被称为比执行时更快,导致重叠并执行昂贵的任务而不是必要的。 我的目标是在重叠中重叠第一个调用的所有调用只执行一次昂贵的任务。
public static void MethodA() { Console.Write("A"); }
public static Task MethodB() { Console.Write("B"); return Task.Delay(500); }
public static void MethodC() { Console.Write("C"); }
public static async Task MethodAsync() {
//TODO: Block any additional calls until first call has finished.
// Additional calls then exit immediately afterwards.
Console.Write("<");
MethodA();
await MethodB();
MethodC();
Console.Write(">");
}
public static void Main() {
MethodAsync();
MethodAsync();
Console.ReadLine();
}
鉴于上面的示例,MethodAsync被调用两次,没有延迟,导致MethodB执行两次。 我想让第一个调用正常执行,第二个调用等待(异步)直到第一个调用完成,然后退出而不执行任何后续操作。
我提出的最好的方法是使用SemaphoreSlim和一个整数变量:https://dotnetfiddle.net/7H8SZx
我想知道是否有不同/更好的方法来做到这一点。
编辑:
鉴于上面的示例(不是链接),输出将类似于<AB<ABC>C>
。
我的目标是拥有类似<AB<C>>
的内容,或者如果我毫不拖延地拨打10个电话(实际上从未发生过)<AB<<<<<<<<<C>>>>>>>>>>
另一个例子:
MethodAsync方法等待2次没有延迟,然后在2s后等待另外三次没有延迟。
目标是<AB<C>><AB<<C>>>
答案 0 :(得分:0)
信号量是要走的路,但是你可以把它变得比你的小提琴更简单;像这样的东西:
static SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
public static async Task MethodAsync()
{
Console.Write("<");
if (await semaphore.WaitAsync(TimeSpan.Zero))
{
MethodA();
await MethodB();
MethodC();
semaphore.Release();
}
Console.Write(">");
}