I implemented threading in my application for scraping websites. After all the sites are scraped I want to process them.
form creates queueworker(which creates 2 workers and processes tasks). After all the tasks are done I want to process them baack in the formthread. At this point I accieved this with
public void WaitForCompletion() { // Enqueue one null task per worker to make each exit. StopWorkers(); //wait for the workers to finish foreach (Thread worker in workers) { worker.Join(); } }
After a task is preformed I fire (from queueworker):
public event EventHandler<ProgressEvent> UrlScanned; if (UrlScanned != null) { UrlScanned(this, new ProgressEvent(task.Name, 1)); }
And catch that event with:
urlscanner.UrlScanned += new EventHandler<ProgressEvent>(UrlScanningProgress); private void UrlScanningProgress(object sender, ProgressEvent args) { if (pbarurlScan.InvokeRequired) { //don't use invoke when Thread.Join() is used! Deadlock Invoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args); //BeginInvoke(new MethodInvoker(delegate() { UrlScanningProgress(sender, args)}; } else { pbarurlScan.Value++; } }
The problem is that the formthread gets blocked and with calling Invoke the whole application is now in a deadlock situation.
How can I give update to the formthread without having a deadlock and have an immidiate update (begininvoke occurs if the workers threads are done)
Why are you doing the Join? I would raise a callback at the end of each thread – perhaps decrementing a counter. When the counter gets to 0, then call back to the UI thread and do the ‘all done’ code; something like: