始终同步执行未知操作
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
切换到 delegate
(Func
似乎不是一个好的选择,因为我必须指定 return 值类型)但是我没有找到任何可以帮助我的东西。
Action
上的 async lambda 是 async 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
我目前正在开发一个模拟 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
切换到 delegate
(Func
似乎不是一个好的选择,因为我必须指定 return 值类型)但是我没有找到任何可以帮助我的东西。
Action
上的 async lambda 是 async 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