始终同步执行未知操作

Executing an Unknown Action always synchronously

我目前正在开发一个模拟 class 库,其他程序员将使用它来创建动态模拟时间线和 运行 这些模拟。

从某种意义上说,这是通过让库的用户在模拟时间的某些点上指定动作来完成的。

但我现在 运行 遇到了用户创建的操作可以异步或非异步的问题。为了保持模拟的一致性,尽管我需要同步执行两个变体。我把问题归结为一个非常简单的例子:

class Program
{
    static void Main()
    {
        Action action = ActionFromUser();

        action();

        Console.WriteLine("2");

        Console.ReadKey();
    }

    static Action ActionFromUser()
    {
        Random rng = new Random();

        if (rng.Next(0, 2) == 0) // 50/50
        {
            return async () =>
            {
                await Task.Delay(1000);
                Console.WriteLine("1");
            };
        }
        else
        {
            return () =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("1");
            };
        }

    }
}

现在问题归结为输出取决于操作是异步还是同步,这是我想要摆脱的行为。

该操作将始终没有参数且没有 return 值。

不想使用反射(action.Method.IsDefined(typeof(AsyncStateMachineAttribute), ...)。

我尝试从 Action 切换到 delegateFunc 似乎不是一个好的选择,因为我必须指定 return 值类型)但是我没有找到任何可以帮助我的东西。

Action 上的 async lambdaasync void。你不太可能想要这个。如果有疑问,将其更改为 Func<Task> 和 return 已完成的任务 同步 结果,以及 await 结果。

注意:这是一个人为的例子,我想你的代码有很大不同,但它说明了这一点:

static Func<Task> FromUserAsync()
{
    Random rng = new Random();

    if (rng.Next(0, 2) == 0) // 50/50
    {
        return async () =>
        {
            await Task.Delay(1000);
            Console.WriteLine("1");
        };
    }
    else
    {
        return () =>
        {
            Thread.Sleep(1000);
            Console.WriteLine("1");
            return Task.CompletedTask;
        };
    }

}

最后一点,您可能应该捕获同步路径中的任何异常并将它们放在任务中,Task.FromException