我正在编写一些新代码,并希望使用async和await编写它,但调用代码当前不是用异步编写的。是否在异步中编写新代码并将其调用为同步,直到调用代码支持异步?
或者我应该编写代码同步,然后在以后转换它?它会被视为技术债务吗?
public Result Execute( Paramerters parameters ) {
return ExecuteAsync( parameters ).Result;
}
public Task<Result> ExecuteAsync( Paramerters parameters ) {
...
}
Execute
位于接口上,并从尚未异步的其他代码中调用。创建异步版本并从Execute
调用它直到调用Execute
的代码转换为异步是否正确?
我的旧代码是用.net 4.5.1编写的,但尚未转换为异步。
答案 0 :(得分:3)
http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx对于为什么要避免这种情况有一些好处,以及如果不能解决问题,如何解决问题。
然而,
或者我应该编写代码同步,然后在以后转换它?
这可能更容易,而且完全摆脱了这个问题。
它会被视为技术债务吗?
根据定义,它是:
无论如何,您可能需要在未来很好地进行同步通话,以支持这种情况,因此您已经拥有了技术债务,而您只是处理它。
你做已经有了技术债务。你说,“但调用代码目前不是用异步编写的”。那里,那是你的债,已经存在。
如果同步和异步版本相互镜像(非常常见)并且您将方法放在他们的双胞胎旁边,则可以很容易地同时对每个方法进行大多数更改。
答案 1 :(得分:2)
我有一篇关于brownfield async
development主题的MSDN文章 - 即将async
引入同步代码库。有几种不同的方法,每种方法各有利弊。我的偏好是使用flag参数hack,如下:
public Result Execute(Parameters parameters)
{
return ExecuteCoreAsync(parameters, sync: true).GetAwaiter().GetResult();
}
public Task<Result> ExecuteAsync(Parameters parameters)
{
return ExecuteCoreAsync(parameters, sync: false);
}
private async Task<Result> ExecuteCoreAsync(Parameters parameters, bool sync)
{
if (sync)
{
Thread.Sleep(2000); // sync implementation
return new Result();
}
else
{
await Task.Delay(2000); // async implementation
return new Result();
}
}
是的,如果底层操作自然是异步的,那么同步API就是技术债务。
答案 2 :(得分:0)
根据ExecuteAsync的作用,它确实会产生显着的差异。
假设ExecuteAsync执行以下操作:
public Task<Result> ExecuteAsync( Paramerters parameters ) {
List<Task> tasks = new List<Task>();
foreach(var param in parameters)
{
var task = ExecuteSomethingElseAsync(param);
tasks.Add(task);
}
Task.WhenAll(tasks.ToArray());
}
假设ExecutingSomethingelse是IO密集型的,其他任务将执行,而不必等待ExecuteSomething else方法返回一些东西,以便它移动到下一个param。如果您要同步执行此操作,则执行必须等待,并且总执行时间可能会更慢。
如果调用方法,则同步调用anyc方法可能包含一些好处,执行其他异步方法。