为什么异步会减慢独立的后续代码?

时间:2016-08-16 08:55:01

标签: c# asynchronous

我有一个由我的UI线程触发的方法,它加载一些数据。 UI线程不需要立即获取数据。大多数数据来自数据库,有些部分是从文件中读取的。使数据库读取异步后,文件读取速度变慢。

这是我的原始加载方法的样子:

public void load() {
  var sw = new Stopwatch();

  sw.Start();
  db1.loadDB();
  sw.Stop();
  Console.WriteLine("DB1: " + sw.Elapse.Milliseconds);

  sw.Restart();
  db2.loadDB();
  sw.Stop();
  Console.WriteLine("DB2: " + sw.Elapse.Milliseconds);

  sw.Restart();
  db3.loadDB();
  sw.Stop();
  Console.WriteLine("DB3: " + sw.Elapse.Milliseconds);

  sw.Restart();
  file.loadFile();
  sw.Stop();
  Console.WriteLine("File: " + sw.Elapse.Milliseconds);
}

因为每个数据库loadDB方法都执行多个数据库查询,所以我认为以异步方式实现它们可能是个好主意。

public void load() {
  var sw = new Stopwatch();

  sw.Start();
  taskDB1 = db1.loadDBAsync();
  sw.Stop();
  Console.WriteLine("DB1: " + sw.Elapse.Milliseconds);

  sw.Restart();
  taskDB2 = db2.loadDBAsync();
  sw.Stop();
  Console.WriteLine("DB2: " + sw.Elapse.Milliseconds);

  sw.Restart();
  taskDB3 = db3.loadDBAsync();
  sw.Stop();
  Console.WriteLine("DB3: " + sw.Elapse.Milliseconds);

  sw.Restart();
  file.loadFile();
  sw.Stop();
  Console.WriteLine("File: " + sw.Elapse.Milliseconds);
}

在另一个方法中等待任务,当UI线程实际需要数据时调用该方法。

困扰我的是loadFile方法执行所花费的时间。在loadDB的异步实现之前,它们每个完成大约需要100ms,而loadFile方法需要大约20ms才能完成。 loadDBAsync的异步实现大约需要5ms才能完成。但在第二个示例中,loadFile方法需要50ms才能完成。我根本没有改变loadFile方法。

异步数据库访问如何减慢读取文件的速度?

编辑: 添加了我用来衡量时间的代码。 数据库位于同一磁盘上,至少目前是这样。 5ms将提交任务。

1 个答案:

答案 0 :(得分:1)

正如他在评论中提到的BugFinder,你可能会遇到IO瓶颈。

在第一种情况下,您要等到所有数据库操作完成后才能访问该文件。

在第二种情况下,最多可能有四个线程同时访问磁盘,很可能是不同的扇区。因此,每次进行线程上下文切换时都必须旋转磁盘,并且可能有很多这样的。

尝试:

public async Task load()
{
    //all your DB access logic as previously

    await Task.WhenAll(new [] { taskDB1, taskDB2, task DB3 });

    file.loadFile();
}

我想,你的loadFile性能可与第一版相媲美。

相关问题