none
Background Thread RRS feed

  • Question

  • using wpf , i'm generating pdf reports...

    those reports have some resources needed  such as

    :  pics  and pdf cover page.

    i have gave the user the option to select multiple reports to be built...

    in order not to have the main windows freeze... i'm using background worker...

    building a single report is fine...

    the problem arise when building multiple reports...

    at times... a process tries to access a file (pic or pdf) that is being used by another process...

    my code look like thiS:

    foreach

    (varp incheckBoxIsCheck)

                 {

                     workerReports =

    newBackgroundWorker();

                     bookType =

    Convert.ToInt32(p.Id);

                     workerReports.WorkerReportsProgress =

    true;

    workerReports.DoWork += BuildTheReport;

                     workerReports.RunWorkerCompleted += Reports_RunWorkerCompleted;

                     workerReports.ProgressChanged += Reports_Progresschanged;

                     workerReports.RunWorkerAsync();

                 }

    any suggestion are welcome ... thank you

    Wednesday, September 12, 2012 2:36 PM

Answers

  • sorry for the messy code... i cleaned it a bit .. take a look at this below:

    /// <summary>
             /// set up and Fire Up the BackgroundProcess - wokerReports
             /// <para>calls methothd BuildCapturePics() </para>
             /// </summary>
             /// <returns>- </returns>
             /// <remarks> - </remarks>
             void Pics_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs ex)
             {
                 

                 mainStatusLabel.Content = "Generating PDFs Please Wait...";


                 // enable Windows.controls objects
                 var checkBoxIsCheck = allCheckBoxReports
                                      .Select(e => new { e.checkboxReports, e.Id })
                                      .Where(e => e.checkboxReports.IsChecked == true);

                 
                 
                 foreach (var p in checkBoxIsCheck)
                 {
                     bookType = Convert.ToInt32(p.Id);

                     ppaAdminCoreFn.CoreFuntion corefunc = new ppaAdminCoreFn.CoreFuntion();

                     

                     MultiTasks.Add(new Tasking()
                     {
                         taskBookType = bookType,
                         taskDateId = DateId,
                         taskMonthId = MonthId,
                         taskYearId = YearId,
                         theTask = Task.Factory.StartNew(() => {
                             corefunc.GetReport(bookType, DateId, MonthId, YearId);
                         })
                         
                     });



                 }

                 foreach (Tasking iTask in MultiTasks)
                 {
                     iTask.theTask.Wait();
                     tasks.Add(iTask.theTask);
                 }


                 int x = 0;

                

                 Task.Factory.ContinueWhenAny(tasks.ToArray(), taskl =>
                    {
                        
                            Console.WriteLine(" IN");
                        
                    });

             }

    Thursday, September 13, 2012 4:27 PM

All replies

  • One thing that stands out at me is that you're creating a new background worker for each report.  More typically, you'd have a single background worker that handles multple tasks, or perhaps one worker per physical CPU if your tasks are compute intensive and long-running.  You'd then feed work to these background workers through a synchronized queue or other similar thread-safe message passing mechanism. 

    You haven't shown enough code to know for sure whether the problem you're seeing is in any way related to this observation - it depends entirely on what BuildTheReport does.  If that method results in simultaneous access to files that have been opened in a way that does not permit the sharing, then this is likely the source of your problem.  Either open files in a way that permits sharing, or serialize the processing of multiple reports (as outlined above) so that no two are ever in process at the same time.


    -cd Mark the best replies as answers!

    • Proposed as answer by Viresh K Singh Wednesday, September 12, 2012 5:53 PM
    Wednesday, September 12, 2012 4:03 PM
    Moderator
  • thank you Carl Daniel  very much for your response...

    i have to say that im a beginner when it comes to the C# developping...

    this is my firstime using background process.

    i decided to create mutilple background process for each reportbuild because... the background worker would not handle mutiple task.

    but i have to say that you gave new ideas... i ll working on it and update in a few...

    if anyone has some code please do share it

    Wednesday, September 12, 2012 6:14 PM
  • Hi Franck_muke,

    Welcome to the MSDN Forum.

    Please take a look at this code:

            public void Yourmethod()
            {
                foreach (string p in new string[12])
                {
                    Thread t = new Thread(()=>BuildReport(p));
                    t.Start(p);
                }
            }
            public void BuildReport(string reportName)
            {
    
                Console.WriteLine("Build Report " + reportName + "begin");
                //your code here
                Console.WriteLine("Build Report " + reportName + "end");
            }

    It start a thread for every report.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, September 13, 2012 9:20 AM
    Moderator
  • THank you very much for the previous reply mike...

    however , it does not resolve the problem.

    the problem that i'm facing lies in that i need to run thread sequentially ...

    so that when a thread runs only if  all or one thread is finished......

    i'm doing this because  the differents BuildReport thread will access the same resources such as pics and pdfs...

    for this reason i am stepping away from background worker and now working with Task since there is more flexibility but now since i am now with task i still quite don't get it how to work with it... this what i got so far:

    foreach (var p in checkBoxIsCheck)
                 {
                     bookType = Convert.ToInt32(p.Id);

                     ppaAdminCoreFn.CoreFuntion corefunc = new ppaAdminCoreFn.CoreFuntion();

                     //corefunc.GetReport(bookType, DateId, MonthId, YearId);
                     //var task = Task.Factory.StartNew(() => corefunc.GetReport(bookType, DateId, MonthId, YearId));

                     ////task.Wait();

                     MultiTasks.Add(new Tasking()
                     {
                         taskBookType = bookType,
                         taskDateId = DateId,
                         taskMonthId = MonthId,
                         taskYearId = YearId,
                         theTask = Task.Factory.StartNew(() => {
                             corefunc.GetReport(bookType, DateId, MonthId, YearId);
                         })
                         //theTask = new Task(()=>corefunc.GetReport(bookType, DateId, MonthId, YearId))
                         
                     });



                 }

                 foreach (Tasking iTask in MultiTasks)
                 {
                     iTask.theTask.Wait();
                     tasks.Add(iTask.theTask);
                 }


                 int x = 0;

                 //Task.Factory.ContinueWhenAll(tasks.ToArray(), WaitAnyTasksCompleted =>
                 //{
                 //    Console.WriteLine("Success");
                     
                 //});

                 //Task.WaitAll(tasks.ToArray());

                 Task.Factory.ContinueWhenAny(tasks.ToArray(), taskl =>
                    {
                        
                            Console.WriteLine(" IN");
                        
                    });

    Thursday, September 13, 2012 4:24 PM
  • sorry for the messy code... i cleaned it a bit .. take a look at this below:

    /// <summary>
             /// set up and Fire Up the BackgroundProcess - wokerReports
             /// <para>calls methothd BuildCapturePics() </para>
             /// </summary>
             /// <returns>- </returns>
             /// <remarks> - </remarks>
             void Pics_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs ex)
             {
                 

                 mainStatusLabel.Content = "Generating PDFs Please Wait...";


                 // enable Windows.controls objects
                 var checkBoxIsCheck = allCheckBoxReports
                                      .Select(e => new { e.checkboxReports, e.Id })
                                      .Where(e => e.checkboxReports.IsChecked == true);

                 
                 
                 foreach (var p in checkBoxIsCheck)
                 {
                     bookType = Convert.ToInt32(p.Id);

                     ppaAdminCoreFn.CoreFuntion corefunc = new ppaAdminCoreFn.CoreFuntion();

                     

                     MultiTasks.Add(new Tasking()
                     {
                         taskBookType = bookType,
                         taskDateId = DateId,
                         taskMonthId = MonthId,
                         taskYearId = YearId,
                         theTask = Task.Factory.StartNew(() => {
                             corefunc.GetReport(bookType, DateId, MonthId, YearId);
                         })
                         
                     });



                 }

                 foreach (Tasking iTask in MultiTasks)
                 {
                     iTask.theTask.Wait();
                     tasks.Add(iTask.theTask);
                 }


                 int x = 0;

                

                 Task.Factory.ContinueWhenAny(tasks.ToArray(), taskl =>
                    {
                        
                            Console.WriteLine(" IN");
                        
                    });

             }

    Thursday, September 13, 2012 4:27 PM