如何为异步方法创建通用扩展方法?

spr*_*t12 2 c# extension-methods task async-await

我正在尝试创建一个.WithDelay(seconds);可以在异步方法调用结束时添加的方法。

我得到的问题是先调用 async 方法然后延迟发生,我希望它反过来,不切换调用顺序。

例如,我想要await MyMethod().WithDelay(seconds);而不是await WithDelay(seconds).MyMethod();.

这是我到目前为止所拥有的,它首先调用该方法:

public async static Task<T> WithDelay<T>(this Task<T> task, int delay) {
  await Task.Delay(delay);
  return await task;
}
Run Code Online (Sandbox Code Playgroud)

我希望延迟首先发生,然后是实际运行的方法。

Ste*_*ary 7

我想要反过来,而不改变调用顺序。

这是不可能的,因为 C# 语言只支持types上的扩展方法,而不支持methods

您可以获得的最接近的是委托的扩展方法:

public static async Task<T> WithDelay<T>(this Func<Task<T>> func, int delay) {
  await Task.Delay(delay);
  return await func();
}
Run Code Online (Sandbox Code Playgroud)

用法仍然很尴尬:

// Either:
Func<Task<MyType>> func = MyMethod;
var result = await func.WithDelay(1000);

// or (assuming "using static"):
var result = await WithDelay(MyMethod, 1000);

// What you really want, not currently possible:
// var result = await MyMethod.WithDelay(1000);
Run Code Online (Sandbox Code Playgroud)

对于这种类型相关的情况,它可以帮助先同步解决问题,然后将该解决方案转换为async. 如果语言阻碍了良好的同步解决方案,那么它很可能会阻碍良好的异步解决方案。

有一个关于方法的扩展方法的提议,但它不是今天语言的一部分。