【发布时间】:2018-03-22 15:33:30
【问题描述】:
我有一个异步方法,有时调用它的速度比它的执行时间快,这会导致重叠并比必要的更频繁地执行昂贵的任务。 我的目标是让所有调用与重叠中的第一个调用重叠,只执行一次昂贵的任务。
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 次,然后在 2 秒后再次等待 3 次无延迟。
目标是拥有<AB<C>><AB<<C>>>
【问题讨论】:
-
你为什么不等
MethodAsync()? -
我只包含 Main 方法来制作一个工作示例。实际的项目在不同的地方有调用。
-
您没有正确执行此操作,问题不在于等待异步调用。因为您没有使用
await,所以下一个方法开始执行,而第一个方法仍在运行。使用await可以解决这个问题。 -
所以这是一个多线程问题而不是异步/等待问题。您似乎根本不应该使用等待/异步。如果您尝试在另一个线程上执行方法以保持 UI 线程处于活动状态。如果是这种情况,您需要更新您的问题。
-
另一种选择,虽然我不会说它更好:dotnetfiddle.net/YzS2De
标签: c# async-await