BackgroundWorker and resource managemnet in c# - c#

Let suppose I create a background worker in a form as a component.And start it.
Now if I close the form then BackgroundWorker will be still running.
Will you explain that however form has been closed and all resources created within the form object have been closed but BackgroundWorker is still running. What is reason behind this?. Is this because of it is runnibg on a different thread.
And when it resources will be regained by CLR.

The background worker isn't by default connected to the form or thread it's created in.
A background worker is an object like any other object. It will get collected when there are no more active references to it.
So it really depends on how and where the object was created, and mostly - who is still has references to it.
What people tend to forget is that the events are also references. So if there's another object somewhere that is listening to the worker's events, the worker will still be referenced and so it won't be collected.
Note:
Form.Close() removes the dialog from sight and calls the Closing() and Closed() methods. You can still access the form and bring it back later on.
Form.Dispose() destroys the dialog and frees its resources back to the operating system. It does not call the form’s Closing() and Closed() methods. Once disposed, you may not recall a form. The Dispose() will also call the Dispose() method of all the Form's components.

The background worker will be disposed with the form, unless you deliberately suppress dispose. If this is the case then it should be garbage collected at an indeterminate time. I say should because things could potentially hold reference to the background worker. As for the thread, I believe it will be cleaned in the dispose, which should be called from the form when it closes.
If the form is the main form, and on closing causes the main foreground thread to close, then all background threads will close / die also.

When you close your form and dispose it, BackgroundWorker will dispose too, but it does not stop the thread running. So it will be completely destroyed only after the DoWork finishes.
You can solve this by cancelling the closing of the Form and calling CancelAsync on the background worker to signal that you want it to finish. Wait until it finishes and only after that you should actually close the form.

Related

Is it safe to instantiate a form and call ShowDialog from within BeginInvoke?

Is it safe to instantiate a form and call ShowDialog from within BeginInvoke?
BeginInvoke run the task on the same thread on which the control had been created.
So as far as i know should be ok ...
I am just asking if such creation may lead to some hangs, deadlocks, etc..
This is ambiguous, sure sounds like you instantiate the form first and then call BeginInvoke(). No, that's not okay. It will look like it will work since ShowDialog() pumps a message loop. But you'll have a raft of very nasty glitches. The mild stuff is the window not being modal to the other windows in the app. And not having a Z-order relationship with the other windows in your app which can cause it to easily disappear behind another window. Nastier stuff is that the thread probably isn't an STA thread, things like drag + drop, the clipboard and the shell dialogs will not work. The really nasty stuff is getting the SystemEvents class to start firing events on the wrong thread, that problem lasts past the dialog and crashes or hangs your app at unpredictable times later.
Only ever create a form instance on the UI thread. Which means that you must use the BeginInvoke() method of another instance of a form, one that was created earlier. If you are desperate to find one then Application.OpenForms[0] may give you one.
Is it safe to call ShowDialog inside BeginInvoke, it would be a problem if you would call ShowDialog from a background thread.

Do I have to close running BackgroundWorkers when user closes form?

From here Does closing the application stops all active BackgroundWorkers? it seems not.
But from here How to stop BackgroundWorker on Form's Closing event? it seems yes.
So which is it?
(EDIT: I realize that the BackgroundWorkers might exit with an exception. But what's the problem with that? Isn't the point here to not leave running threads which take up resources?)
Closing a Form does not stop all background workers started by that form.
When the entire application ends it will stop all background threads.
Closing the main form (unless you have modified the Main method to do something else) will end the entire application.
Each question you referenced is correct for what it says. If you close the main form, then the entire application will end and the background worker will be closed on its own. If the form that is closing isn't the main form, but some other form, and you want the background worker that it starts to be stopped, then you will need to do so yourself.
It's also worth noting that the second link that you have provided asks for something a bit more complex. It's clear in that post that closing the form (if it's the main form) will stop execution of the background thread. What the OP is trying to do there is to tell the background thread, "hey, it's time to finish up, we're done here" and then have the form wait until that background thread can finish cleaning things up nicely, rather than just exiting and forcibly aborting the thread while it's in the middle of doing something.
Both of those links that you provide have the correct answer- BackgroundWorkers will be closed when the program is closed. Unmanaged resources are the ones you have to worry about explicitly closing.

Open new form from inside each thread?

I'm using the following code to open a new form (that is for user input) in my function:
Form4 f4 = new Form4();
f4.mainform = this;
f4.get_Text(matchString);
f4.ShowDialog();
It's working perfectly when not threading, but when I try to run the function on two threads I only get 1 form popup. How can I adjust it so that it will support more than one thread?
You can open a form from any thread, you just need to start a message loop on the new thread, such as:
Application.Run(f4)
The Run method will not return until the form is closed. It can cause issues, though, so you need to be careful and know what you are doing. Unless it's a real pain to do, I would sooner consider redesigning your code to be more asynchronous. For instance, you could create a event handler method to listen for the form's closing event.
The WIN32 Message pump runs on one thread -- the GUI thread. As soon as you .ShowDialog(), the c# stops until the user closes the dialog. Even if you use .Show() to avoid a "stop and wait for the user to push ok", you still must handle all GUI events on the GUI thread by .Invoke()ing to the GUI thread.
The way to support multi-threaded-ness is by doing non-GUI work on alternate threads.
ShowDialog does pump messages so it would technically work on a separate thread without needing a dedicated message loop. However, what you currently have looks like a recipe for disaster because that form appears to hold a reference to another form via f4.mainform = this and it is presumably trying to access it. You simply cannot do this without littering (and I mean that literally) your code with a bunch of Invoke or BeginInvoke calls.
Furthermore, running UI forms on a thread other than the main UI thread generally does not work well. There are a few obscure problems you can run into. For example, since there would be two UI threads in play it is possible to have 2 active modal dialog boxes open. One might be hidden behind the other and the end user would not see it. This reason, among others, is why it is not generally recommended to use more than one UI thread.
My advice is to figure out a way to make this work with a single UI thread. Your life will be simplier if you do.

Which event will be throw while the form is reloading after hiding the form?

I am having a form in my application Form1. A thread is running in this form. When i am showing the next form Form2, I am hiding this form and aborting the thread.
When I am showing the parent form again , i need to restart the thread again.which event
in the main form I can write thread restart code?
While the VisibleChanged or Activated events may do this, I have to wonder why you don't just do it explicitly - it's your code that will be showing the form again, isn't it? Why not just create a new thread as part of the code that gets executed at that point?
As a side note, if you really are aborting the thread (with Thread.Abort) it would be worth moving to a more graceful shutdown procedure, setting a flag which the thread checks periodically. Hard aborts of threads are prone to leaving the application in an unknown state.

C# UserControl BeginInvoke Problem

I have got a C# user control, which has got it's own background worker thread. This worker thread is started in the constructor of the control and stopped when the control is disposed.
The thread periodically calls the BeginInvoke-Method with a delegate, but sometimes the exception "Invoke or BeginInvoke cannot be called on a control until the window handle has been created." occoures.
Now I ask you, how can I check whether calling BeginInvoke is possible from my worker thread to do no invoking as long as the control isn't completely created?
This problem only occoures when compiling a release. Not in debug mode.
with best regards
The worker thread should be created inside... (you have two options):
A handler of Control.HandleCreated event
Overriding Control.OnHandleCreated
What you need to know is that a control may not be fully created (ready to be used) even after the constructor is done executing.

Categories

Resources