异步从同一数据库的不同视图获取数据

时间:2017-03-21 11:35:57

标签: c# sql .net asynchronous

我想异步地从同一个数据库的5个不同视图中获取数据 - 我使用了以下解决方案:

public async Task<List<Product>> GetProductsAsync()
    {
        string query = $"SELECT  * FROM dbo.v_Products";

        try
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();

            var items = await _dbContext.Database.SqlQuery<Product>(query).ToListAsync();

            sw.Stop();
            Debug.WriteLine("\t " + Thread.CurrentThread.ManagedThreadId + $" getting Products ({items.Count}) seconds: " + sw.Elapsed.TotalSeconds);

            return items;
        }
        catch (Exception ex)
        {
            throw new Exception("Getting Products failed!", ex);
        }
    }

有以下情况:我有~30个数据库,每个都运行一个线程,并执行“GetProductAsync”等方法来收集数据。但我还没有看到使用异步的改进,似乎每个下一个方法的执行时间都包含了之前执行的时间。我哪里错了?

UPD :调用函数

public async Task<DataContext> GetDataAsync()
    {
        DataContext data = new DataContext();

        var items1= await _dac.GetProductsAsync();
        var items2 = await _dac.GetProducts2Async();
        var items3 = await _dac.GetProducts3Async();
        var items4 = await _dac.GetProducts4Async();
        var items5 = await _dac.GetProducts5Async();

        data.items1= items1;
        data.items2= items2;
        data.items3= items3;
        data.items4= items4;
        data.items5= items5;

        return data;
    }

如果我将为每个异步方法执行重新创建数据库上下文,就像这里一样吗?

public async Task<List<Product>> GetProductsAsync()
{
    string query = $"SELECT  * FROM dbo.v_Products";

var ctx = new myDbContext(_dbContext.Database.ConnectionString);

    try
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        var items = await ctx.Database.SqlQuery<Product>(query).ToListAsync();

        sw.Stop();
        Debug.WriteLine("\t " + Thread.CurrentThread.ManagedThreadId + $" getting Products ({items.Count}) seconds: " + sw.Elapsed.TotalSeconds);

        return items;
    }
    catch (Exception ex)
    {
        throw new Exception("Getting Products failed!", ex);
    }
}

3 个答案:

答案 0 :(得分:2)

调用所有Async方法,但稍后调用Await所有方法,

public async Task<DataContext> GetDataAsync()
{
    DataContext data = new DataContext();

    var t1 = _dac.GetProductsAsync();
    var t2 = _dac.GetProducts2Async();
    var t3 = _dac.GetProducts3Async();
    var t4 = _dac.GetProducts4Async();
    var t5 = _dac.GetProducts5Async();

    data.items1 = await t1;
    data.items2 = await t2;
    data.items3 = await t3;
    data.items4 = await t4;
    data.items5 = await t5;

    return data;
}

只要数据库调用的执行时间很短,为每个调用创建新的上下文就不会产生任何问题。每个新连接都使用/重用连接池中的连接,因此您不应该吃掉所有连接。

答案 1 :(得分:1)

很可能是因为

  

同一个上下文实例上的多个活动操作不是   支撑。

你的调用方法完全符合它应该做的事情:

  

使用'await'确保任何异步操作都已完成   在此上下文中调用另一个方法之前。

https://msdn.microsoft.com/en-us/library/dn220262(v=vs.113).aspx

答案 2 :(得分:1)

"minimum-stability": "dev"

有关WhenAll的详细说明,请参阅MSDN Link