【发布时间】:2019-11-21 14:44:15
【问题描述】:
我想让异步方法同步运行。
是的,我知道这是一种不好的做法,但我们需要这样做有几个原因,因此为了这个问题,我们假设我们必须这样做,并且没有其他方法可以达到最终结果。
所以我有我的异步方法
public static async Task AsyncMethod();
如果我这样称呼它:
public static void SyncMethod()
{
Task task = Task.Run(async () => { await AsyncMethod(); });
task.Wait();
}
一切正常。
但是,如果我想概括我的方法并将这个逻辑放在一个单独的方法中,在一个实用程序库中(这样的库与我的 UWP 项目是分开的),该方法永远不会返回。这是不起作用的方法的代码:
public static class Utilities
{
public static void Sync(this Task task)
{
if (task == null)
return;
Task t = Task.Run(async () =>
{
try
{
await task;
}
catch (Exception e)
{
s_log.InfoFormat("Exception while running task {0} due to {1}", task.Id, e.Message);
}
});
t.Wait();
}
}
然后调用我简单的方法:
public static void SyncMethod()
{
AsyncMethod().Sync();
}
谁能解释一下这种二分法?
编辑:
由于问题比较早,所以我澄清一下这个问题的最终目的。
问题不在于如何解决同步与异步反模式。我已经有一个很好的解决方案,我会在问题的第一部分解释它。
此外,还有一个问题(Call async method from sync action methods: Task.Run or ConfigureAwaits(false))解释了解决方案的优缺点等。
问题在于理解为什么这两行代码
Task task = Task.Run(async () => { await AsyncMethod(); });
task.Wait();
“在线”工作,但如果我将它们放在不同的方法中(在另一个库中),它们就不再工作了。
请在此处查找 MVCE:https://github.com/cghersi/UWPExamples/tree/master/SyncAntiPattern
【问题讨论】:
-
它可能正在吞下一个异常——它会在等待时被抛出,而不是在你那里的 try/catch 中,如果我记得的话,而且由于你的方法是无效的,这就是杀死它的原因
-
你就不能
task.Wait()吗? -
这段代码没有任何意义。让我们打个比方。假设您从事递送包裹的业务。工作流程应该是“在我们等待卡车可用时,寻找其他工作要做”。但是你写的工作流程是“雇佣一个工作人员,他写一个待办事项清单,说在你等待卡车可用时找到其他工作要做,然后雇佣另一个工作人员来做那个清单上的事情,并且然后再雇一个工人看前两个工人,直到他们完成为止。”这些都不能让卡车更快地返回;它浪费工人。
-
@CristianoGhersi 您是否可以发布问题的完整示例,以便我们可以将其复制到项目中并运行它并查看行为?
标签: c# asynchronous async-await task