What happens to a form when ThreadPool WaitCallback calls it after it closes?

Suppose that inside a Windows form, I run a long-running task as follows:

ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateDailyTasksChart)); 

Then this function is executed for a while, but I close the window until it finishes.

 private void UpdateDailyTasksChart (object param) { //Call Data Access Layer, go get MySQL Data. But I close the Form. UICallback(chartData); //The Form is closed when this is executed. } 

And now here is what UICallback does:

 private delegate void UICallbackDel(object chartData); private void UICallback (object chartData) { if (InvokeRequired) { this.Invoke(new UICallbackDel(UICallback), chartData); } else { aButtonOnMyForm.Visible = false; //But the Form has been closed! } } 

Curiously, this code is not crashing.

I set breakpoints in the Form_Closed event and executed . I have not yet checked whether the form exists, for example, by declaring its class variable. But I guess that is so.

So the question is: will the GC only collect the form when my stream ends? Or what is happening?

+4
source share
3 answers

There are two points here:

  • If you explicitly delete the form, you can expect to raise an ObjectDisposedException when it delegates a work item.
  • The delegate of your work item contains a link to the form through this , InvokeRequired (which, in turn, refers to this ) and aButtonOnMyForm . Therefore, your form is not suitable for garbage collection until the ThreadPool thread has completed execution. That is why the code does not crash. (Note: this always implicitly available independently.)

Another thing that follows from this is that it is usually wise to unregister external event handlers from the form before this form closes so that you do not create memory leaks. If you register a lambda expression or an anonymous delegate, you need to keep a link to it in order to cancel the registration later. Simply copying and pasting the same code will not work.

+5
source

You can watch .

Basically, you may or may not get an ObjectDisposedException depending on what the GC does when you try to call on the form. You can try and catch it, but it cannot be verified reliably, so this is more of a hack than anything.

+2
source

The garbage collector does not care if the β€œobject” is closed or β€œlocated” or something like that. It only cares if the object is accessible. And in your case, the form is still accessible using this (implicitly or explicitly). That is why your application does not crash.

Of course, if an object is closed or deleted, or something like that, it throws an ObjectDisposedException within its rights or is similar for any method that you call on it. But this, of course, is not necessary.

+2
source

Source: https://habr.com/ru/post/1399670/


All Articles