1

I know there are several threads concerning this topic, but I think mine is different. In my application I open a form where the user can input some parameters for a upcomming printing. This printing is supposed to be run in a background worker. So I fire that background worker with the event "OnFormClosing".

Within that background worker I need to access the GUI and change/read it, so I need a control.Invoke(). "Sometimes" the Invoke keeps stuck at the invoke call itself and doesn't execute the delegate. My main thread is working fine and is not blocked. I still can interact with the GUI doing other stuff. Before posting any code: Are there any other conditions for executing a control.Invoke() other than

  • The main GUI thread is not blocked
  • The contorl must exist, the handle created and not be disposed

The main thread doesn't need to be free and exactly the invoke is called correct? It should continue once the main thread is idle...

Thanks for any help

Update:

Here is the thread situation during that issue: enter image description here The Main thread is executing this:

Application.Run(appContext);

So it is idle. The worker thread is waiting at this line:

fileName = (string)cbPrintFile.Invoke(new Func<String>(() => cbPrintFile.Text));

which is not executed like I state above. cbPrintFile is a combobox

DerApe
  • 3,097
  • 2
  • 35
  • 55
  • You should be using the `ReportProgress` event handler etc. to report to the UI thread. See http://stackoverflow.com/questions/3289920/c-sharp-how-to-report-progress-from-within-a-class-to-a-backgroundworker. – MoonKnight Mar 11 '13 at 09:01
  • 1
    You say that you're opening a form and then firing your background worker on the `OnFormClosing` method. Which controls are you then updating using `control.Invoke()`? If you're trying to update the form that's trying to close, this might be part of your problem... – Dan Puzey Mar 11 '13 at 09:27
  • +1 just for title similarity to 'Control.Invoke() sucks'. – Martin James Mar 11 '13 at 11:07
  • @DanPuzey no, because without the background worker it works – DerApe Mar 11 '13 at 11:38
  • @Killercam I do not want to report any progress to the UI but just read and set some GUI fields – DerApe Mar 11 '13 at 11:39
  • @derape: So, which control are you calling `control.Invoke` on? If you're running code during `OnFormClosing` then the behavioural difference of using a `BackgroundWorker` could be huge. It might help if you posted some code...! – Dan Puzey Mar 11 '13 at 11:40
  • @DanPuzey I updated my post. It is a combobox. Not sure which code would you guys need to help me here – DerApe Mar 11 '13 at 11:57
  • Can you post the entire `OnFormClosing` method? – Dan Puzey Mar 11 '13 at 12:02
  • @DanPuzey the FormClosing Method just runs the backgroundworker, thats all. The method which is run by the worker is quite large...is there something special you are looking for? – DerApe Mar 11 '13 at 12:12

1 Answers1

3

Invoke is "enqueue and wait for it to be processed". If it is becoming "stuck", that suggests that you have deadlocked, for example because the UI thread is still in an event-handler waiting on the worker. If the code is properly de-coupled, you can probably replace the Invoke with BeginInvoke, which allows the worker to continue after queuing the work. Of course, it would also be good to ensure that the UI is never waiting on a worker. This can be done accidentally if trying to hold a lock (on the same object) in both places. You can investigate simply by pausing the application, pressing ctrl+d,t to bring up the threads, and ctrl+d,c to see the call-stack of each in turn.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • "If the code is properly de-coupled, you can probably replace the Invoke with BeginInvoke ", how decoupling helps here , please clear my doubt. – TalentTuner Mar 11 '13 at 09:10
  • I updated my post to show the acutal situation. I agree, that if the main thread were busy this will block it, but it isn't. "BeginInvoke" will not solve this issue right? Because it just will stay there too and will "never" be executed as it is right now. Also, if I need a value read from the GUI, it won't be returned. – DerApe Mar 11 '13 at 11:52