c# - How to know when all my Producer - Consumer jobs have finished -


i have winforms application read several network folders , search files inside folders, function receive list<stirng> folders:

private decimal _numberoffiles; private static list<string> _folders; public delegate void onfileadddelegate(list<string> files); public event onfileadddelegate onfileaddeventhandler; public delegate void onfinishsearchdelegate(); public event onfinishsearchdelegate onfinishsearcheventhandler;  public void searchfiles() {     foreach (string folder in _folders)     {         if (directory.exists(folder))         {             var files = directory.enumeratefiles(folder, "*.doc", searchoption.topdirectoryonly)                 .orderbydescending(x => new fileinfo(x).creationtime).take((int)_numberoffiles).tolist<string>();             if (onfileaddeventhandler != null)                 onfileaddeventhandler(files);         }     }      if (onfinishsearcheventhandler != null)         onfinishsearcheventhandler(); } 

after onfileaddeventhandler(files) event fired producerconsumer class start check list of files found , work (if file ok fired event main ui add files listview):

public class producerconsumer {     public delegate void onfileadddelegate(pcapfiledetails pcapfiledetails);     public event onfileadddelegate onfileaddeventhandler;     public delegate void allfilesprocesseddelegate();     public event allfilesprocesseddelegate allfilesprocessedeventhandler;     private readonly queue<string> _queue;     private int counter;      public producerconsumer(int workercount, ienumerable<string> list)     {         _issearchfinished = true;         _queue = new queue<string>(list); // fill queue         counter = _queue.count; // set counter         (int = 0; < workercount; i++)             task.factory.startnew(consumer);     }      private void consumer()     {         filechecker filechecker = new filechecker();         (; ; )         {             string file;             lock (_queue)             {                 // synchronize on queue                 if (_queue.count == 0) return;  // done                 file = _queue.dequeue(); // file name process             } // release lock allow other consumers access queue             // job             string result = filechecker.check(file); // check file              if (onfileaddeventhandler != null && result ) // in case file ok, fired event main ui                 onfileaddeventhandler(file);              // decrement counter             if (interlocked.decrement(ref counter) != 0)                 continue; // not last              // done - last             if (allfilesprocessedeventhandler != null)                 allfilesprocessedeventhandler();             return;         }     } } 

now while search in process ui locked prevent unnecessary clicks , want know when folders finish search unlock. problem because search several folders event allfilesprocessedeventhandler() fired several times , want know when searches finished.

here recursive sample quickio.net

using system; using system.collections.concurrent; using system.threading; using system.threading.tasks; using schwabencode.quickio;  namespace consoleapplication3 {     internal class program     {         private static readonly blockingcollection<quickiofileinfo> fileinfos = new blockingcollection<quickiofileinfo>();         private static void main(string[] args)         {             var task = task.factory.startnew(() =>             {                 int32 totalsize = 0;                 parallel.foreach(fileinfos.getconsumingenumerable(), fi =>                 {                     interlocked.add(ref totalsize, (int)fi.bytes);                 });                 console.writeline("all docs bytes amount {0}", totalsize);             });              processdirectory("c:\\");             fileinfos.completeadding();              task.waitall(task);         }          private static void processdirectory(string path)         {             parallel.foreach(quickiodirectory.enumeratedirectories(path), dir =>             {                 try                 {                     parallel.foreach(quickiodirectory.enumeratefiles(dir), file =>                     {                         if (file.asfileinfo().extension.equals(".docx"))                             fileinfos.add(file);                     });                     processdirectory(dir.fullname);                 }                 catch (exception e)                 {                     console.writeline("unable access directory {0}", dir.fullname);                 }             });         }     } } 

blocking collection automatically signal parallel foreach when elements have been added, calling completeadding().

to scan 256gb ssd, 74gb left , total of 738k+ files took 16.8s.


Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

android - Associate same looper with different threads -

visual studio 2010 - Connect to informix database windows form application -