2016-03-04 74 views
3

我正在编写一些新代码并希望使用async编写它并等待,但调用代码当前未用async编写。以异步方式编写新代码并将其称为同步,直到调用代码支持异步为止是正确的吗?在异步中写入新代码但调用同步

或者我应该写代码同步,然后在稍后的日期转换它?这会被视为技术债务吗?

public Result Execute(Paramerters parameters) { 
    return ExecuteAsync(parameters).Result; 
} 

public Task<Result> ExecuteAsync(Paramerters parameters) { 
    ... 
} 

Execute是在一个接口上,并从一些还不是异步的其他代码调用。创建异步版本并从Execute调用它是否正确,直到调用Execute的代码转换为异步? 我的旧代码是用.net 4.5.1编写的,但尚未转换为async。

+4

我强烈建议坚持使用“异步一路下来”的口头禅并立即更新代码。这是一个很好的阅读主题:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html还要记住,“我们将修复其余的稍后“方法很可能是整个软件开发行业最普遍的错觉。不要完成一半的事情。要么使代码异步或不要。 – David

+5

这就是所谓的“异步同步”并且是反模式。它通常是*一个非常糟糕的主意,并且一些异步同步或异步同步的组合可能*完全死锁* ... –

回答

3

http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx在为什么要避免这种情况以及如何减轻问题方面都有一些优点。

然而,

或者我应该写代码同步然后将其转换在以后的日子?

这可能更容易,而且完全摆脱了这个问题。

这会被视为技术债务吗?

根据定义是,虽然:

  1. 您可能需要有同步调用到未来,无论如何,以支持这种情况下,这样你就已经拥有了技术债务,你只是处理它。

  2. 已经有这个技术债务。你说过,“但是调用代码目前不是用async写的”。那里,那是你的债务,已经在那里。

  3. 如果同步和异步版本互相镜像(非常常见),并且将方法放在双胞胎旁边,可以很容易地同时对每个方法进行大部分更改。

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其他方法,以便返回的东西为它移动到下一个PARAM执行。如果您要同步执行此操作,则执行将不得不等待,并且总执行时间可能会变慢。

如果被调用的方法执行其他异步方法,则同步调用anyc方法可能包含一些好处。

+0

我的代码正在执行数据库调用 –

2

我有一个有关brownfield async development主题的MSDN文章 - 也就是将async引入同步代码库。有几种不同的方法,每种方法都有自己的优点和缺点。我的选择是使用标志参数黑客,因为这样的:

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是技术债务。