【问题标题】:Async getting data from different views of the same database异步从同一数据库的不同视图获取数据
【发布时间】:2017-03-21 11:35:56
【问题描述】:

我想从同一个数据库的 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);
    }
}

【问题讨论】:

  • 请贴出实际调用该函数的代码
  • await 阻止执行,因此您的 5 个查询一个接一个地依次运行

标签: c# sql .net asynchronous


【解决方案1】:

稍后调用所有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;
}

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

【讨论】:

  • 请看一下我上面关于它的问题 - 可以吗?
【解决方案2】:

很可能是因为

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

你的调用方法完全按照它应该做的:

使用“等待”确保所有异步操作都已完成 在此上下文中调用另一个方法之前。

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

【讨论】:

    【解决方案3】:
     public async Task<DataContext> GetDataAsync()
    {
        DataContext data = new DataContext();
    //crate individual tasks
        var test1 = _dac.GetProductsAsync();
        var test2 = _dac.GetProducts2Async();
        var test3 = _dac.GetProducts3Async();
        var test4 = _dac.GetProducts4Async();
        var test5 = _dac.GetProducts5Async();
    //Execute all tasks at once with WhenAll function
        await Task.WhenAll(task1, task2, task3, task4, task5); 
    //This statement is executed only after all the tasks are finished  
        return data;
    }
    

    请参阅 MSDN Link 了解有关 WhenAll 的详细说明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      相关资源
      最近更新 更多