简体   繁体   中英

Using Task Parallel Library in API

I have a method where I would like to run three queries in parallel. I am trying to use Task Parallel library to do so as shown:

        internal static async Task<RequestAppointmentDBMasterObject> GetDAMasterObject(string facility, string sites, string state)
        {
            
            RequestAppointmentDBMasterObject mo = new RequestAppointmentDBMasterObject();

            string querySites = query1;
            string queryPractitioners = query2;
            string queryExistingAppts = query3;

        using (IDbConnection db = new OdbcConnection(connectionString))
        {
            await Task.Run(() =>
            {
                Parallel.Invoke(
                    () => { mo.SiteList = db.Query<Sites>(querySites).ToList(); },
                    () => { mo.PractitionerList = db.Query<Practitioners>(queryPractitioners).ToList(); },
                    () => { mo.ExistingAppointments = db.Query<AvailResponseObject>(queryExistingAppts).ToList(); }
                );
            });
        }

            return mo;
        }

Then, on another class I am calling this method to set the object I am going to work with as shown below:

        RequestAppointmentDBMasterObject mo = DataAccess.GetDAMasterObject(facility, site, state).Result;

The problem is that I never get a result back when I call the API. Once I change everything back to not use the Task and Parallel libs. everything works fine. I also tried this same code in a Console App and I got data back. I am not sure why I might be missing on the code so I can use this on my API. Thank you in advance.

This is massively more complex than needed. Having layers of tasks wrapper others is not generally the right approach.

You would be better performing the three queries as async operations (ie. they return Task<T> , and then awaiting them in parallel:

var t1 = db.QueryAsync(...);
var t2 = db.QueryAsync(...);
var t3 = db.QueryAsync(...);

await Task.WhenAll(t1, t2, t3);

This does depend on the database connection supporting multiple concurrent connections (this is generally not true).

Use t1.Result etc. to get the returned values.

As noted in the comments, you don't want to use Parallel at all. Instead, use asynchronous concurrency ( await Task.WhenAll ).

However, most database providers do not allow multiple simultaneous requests over the same database connection. So you will probably need to have three different db connections to run three queries concurrently.

internal static async Task<RequestAppointmentDBMasterObject> GetDAMasterObject(string facility, string sites, string state)
{
  RequestAppointmentDBMasterObject mo = new RequestAppointmentDBMasterObject();
  string querySites = query1;
  string queryPractitioners = query2;
  string queryExistingAppts = query3;

  using (IDbConnection db1 = new OdbcConnection(connectionString))
  using (IDbConnection db2 = new OdbcConnection(connectionString))
  using (IDbConnection db3 = new OdbcConnection(connectionString))
  {
    var task1 = db1.Query<Sites>(querySites).ToListAsync();
    var task2 = db2.Query<Practitioners>(queryPractitioners).ToListAsync();
    var task3 = db3.Query<AvailResponseObject>(queryExistingAppts).ToListAsync();
    await Task.WhenAll(task1, task2, task3);
    mo.SiteList = await task1;
    mo.PractitionerList = await task2;
    mo.ExistingAppointments = await task3;
  }
  return mo;
}

Doing multiple concurrent queries like this is possible , but it's usually better to do a single query that gets everything back all at once. That way you only need a single db connection, and all the query results are consistent with each other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM