Help with synchronization from a unit test in C# -


i'm testing class wraps backgroundworker perform operation away ui thread in application.

the test below fails if timeout exceeded , passes if progresseventcount reaches expected number of events before then.

my question synchronization. asyncexecutor.progressed fired thread pool thread backgroundworker using , test thread reads in while loop.

am using lock correctly?

    [test]     [timeout(1250)]     public void execute()     {         var locker = new object();         const int numberofevents = 10;         const int frequencyofevents = 100;         var start = datetime.now;         int progresseventcount = 0;          igradualoperation tester = new testgradualoperation(numberofevents, frequencyofevents);          var asyncexecutor = new asynchronousoperationexecutor();          asyncexecutor.progressed += (s, e) => { lock (locker) progresseventcount++; };          asyncexecutor.execute(tester);          while (true)         {             int count;             lock (locker)             {                 count = progresseventcount;             }             if (count < numberofevents) continue;             assert.pass("succeeded after {0} milliseconds", (datetime.now - start).totalmilliseconds);         }     }   //  implementation public class asynchronousoperationexecutor {     public void execute(igradualoperation gradualoperation)     {         var backgroundworker = new backgroundworker {workerreportsprogress = true};          backgroundworker.dowork += backgroundworkerdowork;         backgroundworker.progresschanged += backgroundworkerprogresschanged;         backgroundworker.runworkerasync(gradualoperation);     }      private void backgroundworkerprogresschanged(object sender, progresschangedeventargs e)     {         var myargs = e.userstate progresseventargs;         onprogressed(myargs);     }      static void backgroundworkerdowork(object sender, doworkeventargs e)     {         var workerthis = sender backgroundworker;         var operation = e.argument igradualoperation;          if (workerthis == null || operation == null) return;          operation.progressed += (s, e1) => workerthis.reportprogress((int)e1.percentage, e1);          operation.run();     }      private void onprogressed(progresseventargs e)     {         if (progressed != null)             progressed(this, e);     }      public event eventhandler<progresseventargs> progressed; }   //   test helper class public class testgradualoperation : igradualoperation {     private readonly int _numberofevents;     private readonly int _frequencymilliseconds;      public testgradualoperation(int numberofevents, int frequencymilliseconds)     {         _numberofevents = numberofevents;         _frequencymilliseconds = frequencymilliseconds;     }      public void run()     {         (int = 0; < _numberofevents; i++)         {             thread.sleep(_frequencymilliseconds);             onprogressed(new progresseventargs(i, _numberofevents));         }     }      private void onprogressed(progresseventargs e)     {         if (progressed != null)             progressed(this, e);                 }      public event eventhandler<progresseventargs> progressed; } 

i think revision improvement, blocking test thread , signalling autoresetevent. not winning brownie points test readability though.

    [test]     [timeout(1250)]     public void execute()     {         var locker = new object();         eventwaithandle waithandle = new autoresetevent(false);// <--         const int numberofevents = 10;         const int frequencyofevents = 100;         var start = datetime.now;         int progresseventcount = 0;          igradualoperation tester = new testgradualoperation(numberofevents, frequencyofevents);          var asyncexecutor = new asynchronousoperationexecutor();          asyncexecutor.progressed += (s, e) =>         {             lock (locker)             {                 progresseventcount++;                 waithandle.set();// <--             }         };          asyncexecutor.execute(tester);          while (true)         {             waithandle.waitone();// <--             if (progresseventcount < numberofevents) continue;             assert.pass("succeeded after {0} milliseconds", (datetime.now - start).totalmilliseconds);         }     } 

Comments

Popular posts from this blog

php - What is the difference between $_SERVER['PATH_INFO'] and $_SERVER['ORIG_PATH_INFO']? -

fortran - Function return type mismatch -

queue - mq_receive: message too long -