Print Page | Close Window

What is the most elegant way to execute Paralell Task?

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3870
Printed Date: 20-May-2024 at 12:52pm


Topic: What is the most elegant way to execute Paralell Task?
Posted By: MrTouya
Subject: What is the most elegant way to execute Paralell Task?
Date Posted: 03-Jan-2013 at 4:42pm
Hi Marcel,

I hope I am not the only one asking this one.. What is the most elegant way execute Parallel Tasks with Cocktail 2012? I am trying to accomplish it by doing the following, but I am sure it's not the best way.


private async void InitViewModelData()
        {
            using (Busy.GetTicket())
            {
               BusyContent = string.Format("Initializing Rate Management System...");

               await TaskFns.WhenAll
               (
                  TaskEx.Run(() => Rates = new BindableCollection<RATE_MASTER>(_adminUnitOfWork.Rates.AllAsync().Result)),
                  TaskEx.Run(() => CargoTypes = new BindableCollection<string>(_adminUnitOfWork.CargoTypes.AllAsync().Result.Select(x => x.CARGO_TYPE).Distinct())),
                  TaskEx.Run(() => CargoSubTypes = new BindableCollection<string>(_adminUnitOfWork.CargoSubTypes.AllAsync().Result.Select(x => x.CARGO_SUB_TYPE).Distinct())),
                  TaskEx.Run(() => PortNames = new BindableCollection<string>(_adminUnitOfWork.Ports.AllAsync().Result.Select(x => x.PORT_NAME))),
                  TaskEx.Run(() => ServiceTypes = new BindableCollection<string>(_adminUnitOfWork.ServiceTypes.AllAsync().Result.Select(x => x.SERVICE_TYPE))),
                  TaskEx.Run(() => UnitsOfMeasure = new BindableCollection<string>(_adminUnitOfWork.UnitsOfMeasure.AllAsync().Result.Select(x => x.UNIT_OF_MEASURE))),
                  TaskEx.Run(() => CustomerMasterList = new BindableCollection<CUSTOMER_MASTER>(_adminUnitOfWork.Customers.AllAsync().Result))
               );
            }

            UpdateData();
        }

Thanks,

Stephane



Replies:
Posted By: mgood
Date Posted: 04-Jan-2013 at 1:33am
Doing it like this will actually create cross-threading issues in the EntityManager, because TaskEx.Run executes the action on a different thread, so it's gonna try to use the EntityManager from a thread other than the one that created it. 

The cleanest and most robust way is to create async methods for each one and then execute them in parallel. 

For example.

private async Task LoadRatesAsync()
{
     Rates = new BindableCollection<RATE_MASTER>(await _adminUnitOfWork.Rates.AllAsync());
}

private async Task LoadCargoTypesAsync()
{
    CargoTypes = new BindableCollection<string>(await _adminUnitOfWork.CargoTypes.FindAsync(q => q.Select(x => x.CARGO_TYPE), x => true, fetchOptions: options => options.Distinct());
}

and then you can do:

await TaskFns.WhenAll(LoadRatesAsync(), LoadCargoTypesAsync());

Also, notice the proper way of doing those distinct projection queries. The way you have it performs much poorer because it loads all the entities in the cache and then does the projection and distinct in memory. If you only need the distinct list of something, do it in the database for better performance. 


Posted By: MrTouya
Date Posted: 04-Jan-2013 at 4:59am
Thanks Marcel! I thought I was on to something. Thanks for putting me back on track. David had suggested this method before, but I thought I had discovered another method.

Also, I think I put this post in the wrong forum. Can you move it to the Cocktail Forum?

Stephane


Posted By: mgood
Date Posted: 04-Jan-2013 at 5:15am
I moved the thread.



Print Page | Close Window