0

I want to fetch data from 5 different views of the same database asynchronously - I used the following solution:

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);
        }
    }

There is the following situation: I have ~30 databases, a thread is ran for each one and methods like "GetProductAsync" are executed for gathering data. But I haven' see improvement of using async, it seems that time of execution of each next method contains the time of execution of previous. Where could I be wrong?

UPD: Calling the function

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;
    }

Is it OK if I will recreate db context for each async method execution, like here?

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);
    }
}
2
  • 1
    Please post the code that actually calls this function Commented Mar 21, 2017 at 11:37
  • 3
    await blocks execution, so your 5 queries run sequentially one after other Commented Mar 21, 2017 at 11:48

3 Answers 3

2

Call all Async methods but Await all of them later,

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;
}

Creating new context for each call is not going to create any problem as long as the execution time of database call is small. Each new connection uses/reuses connection from a connection pool so you should not eat up all of it.

Sign up to request clarification or add additional context in comments.

1 Comment

Please, take a look at the my question above about it - is it OK?
1

Most probably because

Multiple active operations on the same context instance are not supported.

Your calling method does exactly what it should do:

Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context.

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

Comments

1
 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;
}

Refer MSDN Link for detailed notes on WhenAll.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.