Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Good day all!!!

VS2010 C#4.0

I have 10 tables in an MSSQL database that I want to load into my application.

I have the following methods in my application:

C#
private DataTable LoadTable01() {//load data using stored procedure in to datatable and return datatable}
private DataTable LoadTable02() {//load data using stored procedure in to datatable and return datatable}
private DataTable LoadTable03() {//load data using stored procedure in to datatable and return datatable}
private DataTable LoadTable04() {//load data using stored procedure in to datatable and return datatable}
private DataTable LoadTable05() {//load data using stored procedure in to datatable and return datatable}
...


Now I want to use Tasks to load the data tables. How would I go about doing this.
Reason for wanting to use tasks is that I want to be able to monitor each load method to make sure it loaded correctly, show the status of the load in a label field; i.e.:

"Loading table 01..."
"Loading table 01 complete..."
"Loading table 02..."
"Loading table 02 complete..."
...

And if any of the tables fails to load successfully Task stops loading any of the other remaining tables.

Thanx in advance...


Thanx for the response...
This is what I now have.

C#
TaskScheduler context = TaskScheduler.FromCurrentSynchronizationContext();
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            CancellationToken token = tokenSource.Token;

token.ThrowIfCancellationRequested();

            Task.Factory.StartNew(() =>
            {
                GlobalClass.Bank = LoadBank(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.BloodGroup = LoadBloodGroup(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.Gender = LoadGender(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.MaritalStatus = LoadMaritalStatus(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.MedicalCondition = LoadMedicalCondition(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.MemberSearch = LoadMemberSearch(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.Modifier = LoadModifier(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.PatientSearch = LoadPatientSearch(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.ProviderCategory = LoadProviderCategory(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.RejectionCode = LoadRejectionCode(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.Relationship = LoadRelationship(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.Title = LoadTitle(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.TaskCategory = LoadTaskCategory(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.TaskPriority = LoadTaskPriority(tokenSource);
            }, token).ContinueWith(result =>
            {
                GlobalClass.UserStatus = LoadUserStatus(tokenSource);
            }, token).ContinueWith(result =>
            {
                DataTable menu = LoadUserMenu(tokenSource);
                LoadDynamicMenu(menu);
            }, token).ContinueWith(result =>
            {
                switch (result.Status)
                {
                    case TaskStatus.Canceled:
                        SetSplashScreenText("Error occurred while loading defaults: " + result.Exception.Message);

                        Thread.Sleep(4000);
                        Application.ExitThread();
                        Application.Exit();
                        break;
                    case TaskStatus.Faulted:
                        SetSplashScreenText("Error occurred while loading defaults: " + result.Exception.Message);
                        Thread.Sleep(4000);
                        Application.ExitThread();
                        Application.Exit();
                        break;
                    case TaskStatus.RanToCompletion:
                        break;
                    default:
                        break;
                }
            }).Wait();



        private static DataTable LoadGender(CancellationTokenSource tokenSource)
        {
            SetSplashScreenText("Loading defaults: Genders...");
            Thread.Sleep(100);
            try
            {
                DataTable _DataTable = new dsDefault.GenderDataTable();

                _SqlDataAdapter = SqlDatabase.FillSqlDataAdapter("load_gender", CommandType.StoredProcedure);
                _SqlDataAdapter.Fill(_DataTable);

//how do I catch the exception and send it to task result to exit the application???

                return _DataTable;
            }
            catch (Exception ex)
            {
//send exception to task
                //throw new OperationCanceledException(tokenSource.Token);
                //throw new OperationCanceledException("Error occurred while loading genders: " + ex.Message);
            }
        }


It works the way I want. But now I have another question.
How do I catch the exception and send it to task result to exit the application???
Posted
Updated 26-Mar-13 1:49am
v3

Dear,
Purpose of TPL is simply that you assign your piece of code to task scheduler, so that there is parallel process. In your case, you have different calls to DB, so its better to use TPL. But reason you mentioned of using task (Reason for wanting to use tasks is that I want to be able to monitor each load method to make sure it loaded correctly) is totally not purpose of TPL.

if you want to use status message of loading and loaded, you can get this easily using Task continuation (Please look Task Continuation in below link given).
But as your requirement given above, load table 1, then load table 2, then load table 3...., It means you are depending one task with other, In other words, your second task will wait, until first one execute successfully. Personally I don't recommend this approach. Use TPL with full advantage, Let your program to process all 10 methods independently.
to learn more about TPL 4.0, I would recommend you one of the best Article

Task Parallel Library: 1 of n[^]



Any way Below is sample code for your, both Synchronize call and asynchronise call.

C#
//In Below example Table 1 will load first, then table 2 and so on.

Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Loading Table1 .... ");
                //Implement you method.
            }).ContinueWith(res =>
            {
                Console.WriteLine("Table1 loaded .... ");
            }).ContinueWith(res => 
            {
                Console.WriteLine("Loading Table 2 ...");
                 //Implement you method.
            }).ContinueWith(res =>
            {
                Console.WriteLine("Table2 loaded .... ");
            });


// Below code all Table will retrieved in random order i.e table1, table3, table5 etc.
//this sequence is totally dependent on Task Scheduler.

Task t1 = Task.Factory.StartNew(() =>
             {
                 Console.WriteLine("Loading Table1 .... ");
                 //Implement you method.
             }).ContinueWith(res =>
             {
                 Console.WriteLine("Table1 loaded .... ");
             });

            Task t2 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Loading Table2 .... ");
                //Implement you method.
            }).ContinueWith(res =>
            {
                Console.WriteLine("Table2 loaded .... ");
            });

            Task t3 = Task.Factory.StartNew(() =>
            {
                Console.WriteLine("Loading Table3 .... ");
                //Implement you method.
            }).ContinueWith(res =>
            {
                Console.WriteLine("Table3 loaded .... ");
            });


            Task.WaitAll(t1, t2, t3);
 
Share this answer
 
The overheads of using the Task library wouldn't be worth it for what you are trying to do.

Personally I would look at using a using BackgroundWorker thread as this will stop your UI from freezing and allows you to update controls on the form easier than Tasks


BackgroundWorker thread[^]
MSDN : BackgroundWorker Class[^]
 
Share this answer
 
Comments
azinyama 26-Mar-13 8:08am    
Thanx...

Let me look in to that. Never used BackgroundWorker before. Question about the BackgroundWorker; There is stuff that happens after the data is loaded. With the BackgroundWorker can I finish loading the data first and then continue like that Task.Wait() does???

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900