Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. WorkerEventHandler.BeginInvoke() questions.

WorkerEventHandler.BeginInvoke() questions.

Scheduled Pinned Locked Moved C#
questiondatabasedesignregexarchitecture
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Are Jay
    wrote on last edited by
    #1

    I have an application that is reading thousands of rows form an access database running calculations then updating the data. I'm using an Async. Design pattern that I'd found on MSDN and am getting my butt handed to me. public void StartRecalculation() { try { FillArrayList(); for ( int num = 0; num < m_Manifest.Count; num++ ) { // Task IDs are Guids. Guid taskId = Guid.NewGuid(); // Start the asynchronous task. this.CalculateStartAsync( Int32.Parse( m_Manifest[ num ].ToString() ), taskId ); } // end of for loop. } // end of try catch ( Exception ex ) { AddToErrorReport( ex.ToString() ); }// end of catch } // end of StartRecalculation public void CalculateStartAsync( int _ticket, object taskId ) { // Create an AsyncOperation for taskId. AsyncOperation asyncOp = AsyncOperationManager.CreateOperation( taskId ); // Multiple threads will access the task dictionary, // so it must be locked to serialize access. lock ( userStateToLifetime.SyncRoot ) { if ( userStateToLifetime.Contains( taskId ) ) { throw new ArgumentException( "Task ID parameter must be unique", "taskId" ); } // end of userStateToLifetime.Contains( taskId ) userStateToLifetime[ taskId ] = asyncOp; } // end of lock this // Start the asynchronous operation. WorkerEventHandler workerDelegate = new WorkerEventHandler( CalculateWorker ); workerDelegate.BeginInvoke( _ticket, asyncOp, null, null ); } //end of CalculateStartAsync My question is when creating the WorkerEventHandler ie.. WorkerEventHandler workerDelegate = new WorkerEventHandler( CalculateWorker ); And then calling the BeginInvoke workerDelegate.BeginInvoke( _ticket, asyncOp, null, null ); Is this creating a new instance of the CalculateWorker Method and other referenced methods? Will I need to isolate my tableAdapters to each method and create new each time or will I be able to us a global Dataset to store and manipulate the inforamtion. I'm having trouble completing anything within my database. I'm getting random rows not found and outOfIndex exceptions. If anyone has any advice on the topic, please help. thanks.

    I'm listening but I only speak GEEK.

    L 1 Reply Last reply
    0
    • A Are Jay

      I have an application that is reading thousands of rows form an access database running calculations then updating the data. I'm using an Async. Design pattern that I'd found on MSDN and am getting my butt handed to me. public void StartRecalculation() { try { FillArrayList(); for ( int num = 0; num < m_Manifest.Count; num++ ) { // Task IDs are Guids. Guid taskId = Guid.NewGuid(); // Start the asynchronous task. this.CalculateStartAsync( Int32.Parse( m_Manifest[ num ].ToString() ), taskId ); } // end of for loop. } // end of try catch ( Exception ex ) { AddToErrorReport( ex.ToString() ); }// end of catch } // end of StartRecalculation public void CalculateStartAsync( int _ticket, object taskId ) { // Create an AsyncOperation for taskId. AsyncOperation asyncOp = AsyncOperationManager.CreateOperation( taskId ); // Multiple threads will access the task dictionary, // so it must be locked to serialize access. lock ( userStateToLifetime.SyncRoot ) { if ( userStateToLifetime.Contains( taskId ) ) { throw new ArgumentException( "Task ID parameter must be unique", "taskId" ); } // end of userStateToLifetime.Contains( taskId ) userStateToLifetime[ taskId ] = asyncOp; } // end of lock this // Start the asynchronous operation. WorkerEventHandler workerDelegate = new WorkerEventHandler( CalculateWorker ); workerDelegate.BeginInvoke( _ticket, asyncOp, null, null ); } //end of CalculateStartAsync My question is when creating the WorkerEventHandler ie.. WorkerEventHandler workerDelegate = new WorkerEventHandler( CalculateWorker ); And then calling the BeginInvoke workerDelegate.BeginInvoke( _ticket, asyncOp, null, null ); Is this creating a new instance of the CalculateWorker Method and other referenced methods? Will I need to isolate my tableAdapters to each method and create new each time or will I be able to us a global Dataset to store and manipulate the inforamtion. I'm having trouble completing anything within my database. I'm getting random rows not found and outOfIndex exceptions. If anyone has any advice on the topic, please help. thanks.

      I'm listening but I only speak GEEK.

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi Arejay, I am not a db specialist at all, but this may help: your code starts a number of threads each executing the "CalculateWorker" method. BTW: methods dont get instantiated, they just get executed, using the local context (e.g. the stack belonging to the executing thread). So the app has several threads executing the same code, if that code refers to global data (all your class members) you may get concurrency problems. If for instance you create and use some object (maybe a table adapter) and suddenly that object gets manipulated by multiple threads, anything can happen. Rather than using such shared data (and trying to add all necessary locks), I would advise to give each thread its own data, i.e. instantiate a "job" object for each thread you create (better yet, create the thread inside the job object). Hope this helps. :)

      Luc Pattyn [My Articles]

      A 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi Arejay, I am not a db specialist at all, but this may help: your code starts a number of threads each executing the "CalculateWorker" method. BTW: methods dont get instantiated, they just get executed, using the local context (e.g. the stack belonging to the executing thread). So the app has several threads executing the same code, if that code refers to global data (all your class members) you may get concurrency problems. If for instance you create and use some object (maybe a table adapter) and suddenly that object gets manipulated by multiple threads, anything can happen. Rather than using such shared data (and trying to add all necessary locks), I would advise to give each thread its own data, i.e. instantiate a "job" object for each thread you create (better yet, create the thread inside the job object). Hope this helps. :)

        Luc Pattyn [My Articles]

        A Offline
        A Offline
        Are Jay
        wrote on last edited by
        #3

        Thank you! So... I've created a worker class and I'm creating multiple instances of the worker. Within the worker class I create an asyn thread using the BeginInvoke. Now I need update the calling form. public delegate void CalculationCompletedEventHandler( object sender, CalculationCompletedEventArgs e ); In the Worker class: public class Worker : Component { //... public event CalculationCompletedEventHandler CalculationCompleted; //.. private void doCalculationCompleted( object operationState ){ CalculationCompletedEventArgs e = operationState as CalculationCompletedEventArgs; OnCalculationCompleted( e ); } protected void OnCalculationCompleted( CalculationCompletedEventArgs e ){ if ( CalculationCompleted != null ) { CalculationCompleted( this, e ); } } On the form: internal void OnUpdateProgress( object sender, CalculationCompletedEventArgs e ){ if ( this.InvokeRequired ){ this.Invoke( doProgressUpdate, new object[] { sender, e } ); }else{ lock ( this ){ //....Do Stuff } } } Worker w = new Worker(id); w.CalculationCompleted += OnUpdateProgress; In the above is the doCalculationCompleted method needed in the Worker Class? I'll update my code and let you know how it went. Thanks again.

        I'm listening but I only speak GEEK.

        L 1 Reply Last reply
        0
        • A Are Jay

          Thank you! So... I've created a worker class and I'm creating multiple instances of the worker. Within the worker class I create an asyn thread using the BeginInvoke. Now I need update the calling form. public delegate void CalculationCompletedEventHandler( object sender, CalculationCompletedEventArgs e ); In the Worker class: public class Worker : Component { //... public event CalculationCompletedEventHandler CalculationCompleted; //.. private void doCalculationCompleted( object operationState ){ CalculationCompletedEventArgs e = operationState as CalculationCompletedEventArgs; OnCalculationCompleted( e ); } protected void OnCalculationCompleted( CalculationCompletedEventArgs e ){ if ( CalculationCompleted != null ) { CalculationCompleted( this, e ); } } On the form: internal void OnUpdateProgress( object sender, CalculationCompletedEventArgs e ){ if ( this.InvokeRequired ){ this.Invoke( doProgressUpdate, new object[] { sender, e } ); }else{ lock ( this ){ //....Do Stuff } } } Worker w = new Worker(id); w.CalculationCompleted += OnUpdateProgress; In the above is the doCalculationCompleted method needed in the Worker Class? I'll update my code and let you know how it went. Thanks again.

          I'm listening but I only speak GEEK.

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Hi Arejay, you can do with and without a completion event. WITH: the callee provides such an event, caller attaches something to it. WITHOUT: the caller implements some interface (say IDone, with a Done() method), and the callee's constructor accepts an object argument that implements that interface; when done the callee just executes the IDone, hence executing the caller's Done() code. The advantage of events (being able to attach multiple delegates) typically is of no value in the given situation... PS: two remarks about your OnUpdateProgress method: - it invokes doProgressUpdate, the normal pattern is to invoke itself - the lock may not be needed, since the else part executes on the UI thread, hence needs not to be re-entrant. (If other pieces of code contain the same lock and execute on another thread, net result is such thread may keep the UI thread from running, which may harm the responsiveness) Regards. :)

          Luc Pattyn [My Articles]

          A 1 Reply Last reply
          0
          • L Luc Pattyn

            Hi Arejay, you can do with and without a completion event. WITH: the callee provides such an event, caller attaches something to it. WITHOUT: the caller implements some interface (say IDone, with a Done() method), and the callee's constructor accepts an object argument that implements that interface; when done the callee just executes the IDone, hence executing the caller's Done() code. The advantage of events (being able to attach multiple delegates) typically is of no value in the given situation... PS: two remarks about your OnUpdateProgress method: - it invokes doProgressUpdate, the normal pattern is to invoke itself - the lock may not be needed, since the else part executes on the UI thread, hence needs not to be re-entrant. (If other pieces of code contain the same lock and execute on another thread, net result is such thread may keep the UI thread from running, which may harm the responsiveness) Regards. :)

            Luc Pattyn [My Articles]

            A Offline
            A Offline
            Are Jay
            wrote on last edited by
            #5

            I've post a newer version of the application with the connection strings cleaned up and the database has been srunk down. Are Jay's Profile Page[^]

            I'm listening but I only speak GEEK.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups