执行多个数据库调用 - 单线程还是多线程?

时间:2014-08-19 07:06:06

标签: c# wpf mvvm async-await

我试图了解在执行多个数据库调用时最好采用哪种方法。我有很多包含相同模式的屏幕:

  • 在屏幕加载时异步获取数据(async / await)
  • 将控制权返回给UI线程,以便加载屏幕
  • 在某些时候在数据到达时更新UI

某些屏幕只有一个数据库调用,而某些屏幕有多个数据库调用。

典型的数据库调用

private Task<List<Product>> GetProductsAsync()
    {
        TaskCompletionSource<List<Product>> tcs = new TaskCompletionSource<List<Product>>();
        TaskEx.Run(() => tcs.SetResult(Repository.GetAllProducts()));
        return tcs.Task;
    }

单次通话屏幕上的使用

// an event handler,can be marked as async void
public override async void OnActivated()
{
    base.OnActivated();
    ProductList = await GetProductsAsync();
}

在多次通话的屏幕上使用

// an event handler,can be marked as async void
public override async void OnActivated()
{
    base.OnActivated();
    ProductList = await GetProductsAsync();
    CustomerList = await GetCustomersAsync();
    OtherList = await GetOthersAsync();
}

正如您所看到的,当前实现将通过多次调用从屏幕上的线程池中生成多个线程。这是正确的做法吗?

另一种方法是检索一个Task中的所有数据,但这会导致在tcs.Result中检索一个列表数组,这有点不清楚是什么被检索(从代码可读性的角度来看)。

你在自己的线程中执行每个数据库调用的事情是正确的方法,如果没有,你的建议是什么?

1 个答案:

答案 0 :(得分:1)

当您使用async-await时,所有呼叫都可以在不同的线程上运行,但不一定在同一时间(并发)。在您的情况下,所有调用都是顺序的,因此您不会同时访问数据库。

关于对数据库的并发调用,它取决于数据库本身。大多数数据库可以同时处理多个调用,尤其是在不同的表上。但是,如果并发操作使用相同的锁,则可能会增加争用。它可以采用任何一种方式,但在大多数情况下,对数据库的并发调用是一件好事。


关于GetProductsAsync为什么使用TaskCompletionSource而不是:

private Task<List<Product>> GetProductsAsync()
{
    return Task.Run(() => Repository.GetAllProducts());
}