是否有一种通用方法来定义既不接收 Action 也不接收 Func<Task> 的方法?

Is there a generic way of defining a method that receives neither an Action or a Func<Task>?

我有一个方法 A,它通过 运行 前后的一些逻辑来包装另一个方法 B 的执行。方法 B 可以是任务也可以不是。所以为了能够 await 当方法 B 是任务时,我必须像这样实现两次 A 方法:

public async Task A(int id, Action<int> b)
{
    try
    {
        await BeforeAsync(id);
        b(id);
        await AfterAsync(id);
    }
    catch (Exception ex)
    {
        Handle(ex, id);
    }
}

public async Task A(int id, Func<int,Task> b)
{
    try
    {
        await BeforeAsync(id);
        await b(id);
        await AfterAsync(id);
    }
    catch (Exception ex)
    {
        Handle(ex, id);
    }
}

有没有办法避免重复?

不是真的,假设一些愚蠢的事情,比如传递一个对象并用强制转换计数来测试它:)

这个呢?

public Task A(int id, Action<int> b) => A(id, x => { b(a); return Task.CompletedTask; });

这样你就不会重复代码。

是的,有:

public async Task A(int id, Delegate b)
{
    try
    {
        await BeforeAsync(id);
        if (b.DynamicInvoke(id) is Task task) await task;
        await AfterAsync(id);
    }
    catch (Exception ex)
    {
        Handle(ex, id);
    }
}

但是现在你失去了类型安全(因为你可以传递任何委托)并且一无所获。

Task.Run 有 8 个重载是有原因的:https://referencesource.microsoft.com/#q=task.run

使用 RX 观察者模式实现。

source.Subscribe(o => Log.Write($"On Next {o}"));

或者如果您指定额外的前置条件和 post 条件

source
  .Do(_ => Log.Write("Before"))
  .Finally(()=> Log.Write("After"))
  .Subscribe(
    o => Log.Write($"On Next {o}"),
    exception => Log.Write($"On Error {exception}")
    () => Log.Write("On Completed"));

的问题
try
{
    await BeforeAsync(id);
    b(id);
    await AfterAsync(id);
}

是你会假设下面的Catch实际上会捕获所有的异常,但事实并非如此,它只有在你等待或等待它时才会发生。简而言之,正确执行它要复杂得多。