3

我正在编写一些新代码,并想使用 async 和 await 编写它,但调用代码当前不是用 async 编写的。以异步方式编写新代码并将其称为同步直到调用代码支持异步是否正确?

或者我应该编写代码同步然后在以后转换它?它会被视为技术债务吗?

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

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

Execute位于接口上,并从其他尚未异步的代码中调用。Execute创建异步版本并从代码调用Execute转换为异步之前调用它是否正确?我的旧代码是用 .net 4.5.1 编写的,但尚未转换为异步。

4

3 回答 3

3

http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx对于为什么要避免这种情况以及如果不能解决问题如何缓解问题都有一些好处。

然而,

或者我应该编写代码同步然后在以后转换它?

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

它会被视为技术债务吗?

但是,根据定义,它是:

  1. 无论如何,您可能需要在未来进行同步调用,以支持这种情况,因此您已经拥有技术债务,您只是在处理它。

  2. 确实已经有技术债务了。您说,“但调用代码当前不是异步编写的”。那里,那是你的债务,已经在那里了。

  3. 如果同步和异步版本相互镜像(非常常见),并且您将方法放在它们的孪生方法旁边,则可以很容易地同时对每个方法进行大多数更改。

于 2016-03-04T14:37:46.317 回答
2

我有一篇关于棕地async开发主题的 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 就是技术债。

于 2016-03-05T21:10:24.550 回答
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 方法返回某些内容以便它移动到下一个参数。如果您要同步执行此操作,则执行将不得不等待并且总执行时间可能会更慢。

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

于 2016-03-04T14:59:31.703 回答