Calling another form difference in VB.NET - vb.net

What is the difference between these?
A.)
Using xForm as New frmCall()
xForm.ShowDialog()
End Using
B.)
Dim xForm as new frmCall()
xForm.ShowDialog()
xForm.Dispose
C.)
frmCall.Show()
They are all showing the form, and I know it has a difference. What is it?

Aside from the Dispose() (which was covered by Reed), Show() and ShowDialog() are a big difference.
ShowDialog() is a blocking call, which means the methods doesn't exit until the dialog you just popped up on the screen has been dismissed. Dialogs sit on top of your application and prevent you from interacting with the other forms beneath. This all is called "modal" behavior.
Show() does not block. The method will make the form visible and then continue on. You can show several forms this way and click/switch between them with no restrictions.

The first two examples are very similar.
The main difference is that, in the first case, the Dispose call will still occur if an exception is raised inside ShowDialog. In "B", if you raise an exception in ShowDialog, the Dispose call will never occur.
The last option will never call Dispose on the frmCall instance.

Related

How should you reload a form and have it re-initialize?

A older application loads some forms using implicit instances:
form2.showdialog()
Sometime between VS2008 32-bit and VS2013 64-bit, the forms stopped being initialized when they are reloaded. For example, if you load a form, close the form (using the Close method), and load the form again, the classes and controls (and, I assume, the form) are not initialized as new instances.
Re-initialization can be accomplished by putting me.dispose() in the FormClosed event, or by using an explicit instance of the form:
Using frm As New Form2
frm.ShowDialog()
End Using
Is there a good reason to use one of these methods over the other, or is there another method that should be used to cause a form to be initialized when it is reloaded?
Dispose will be called automatically if the form is shown using the Show method. If another method such as ShowDialog is used (your case it is), or the form is never shown at all, you must call Dispose yourself within your application. You can also handle the dispose by moving it from the designer file into the code file and handle things there as well.
On the other hand, Using statement typically makes your application safer to maintain and less prone to deadlocks and other misbehavior related to the lifecycle of the resource. I would stick by using this approach.
Also you cant put Me.Dispose in the Form Closed event (possible issues). If your using ShowDialog it will fail as it will dispose your objects first, if you need them they are gone.
Here's more on dispose: https://msdn.microsoft.com/en-us/library/aw58wzka(v=vs.110).aspx
The Form object and its child controls are not automatically disposed when you display the form with ShowDialog(). That sounds pretty quirky but this was done for a very good reason. After ShowDialog returns DialogResult.OK, you are normally going to obtain the dialog results. What nobody likes is that failing because of a ObjectDisposedException. Which would be likely to occur since the dialog results are often stored in controls.
You should always use the Using statement to ensure the form object and all of its controls are disposed.
A possible corner case is intentionally not disposing it because you like the redisplay the dialog with the original entered values. Which is not completely wrong, it is however a very expensive way to preserve those values. Those undisposed window objects cost an arm and a leg in system resources.
Pretty clear explanation from MSDN
Unlike non-modal forms, the Close method is not called by the .NET
Framework when the user clicks the close form button of a dialog box
or sets the value of the DialogResult property. Instead the form is
hidden and can be shown again without creating a new instance of the
dialog box. Because a form displayed as a dialog box is hidden instead
of closed, you must call the Dispose method of the form when the form
is no longer needed by your application.
When ShowDialog() called and closed, instance of the form will remain in the memory, and can be used again, for example get a result from some public property.
If you not using anymore this form, you need to call Dispose method to dispose form and form's controls
Dim myform As New MyDialogForm()
myform.ShowDialog()
Dim result As Object = myForm.SelectedResult()
myform.Dispose() 'need to call manually, if instance not used anymore
When you use Using keyword then Dispose method will be executed automatically at the end of the Using block
Dim result As Object
Using myform As New MyDialogForm()
myform.ShowDialog()
result = myForm.SelectedResult()
End Using 'myform.Dispose will be called
Bottom line: Both methods doing a same things.
But Using block will call Dispose method automatically
P.S. Putting Me.Dispose in the FormClosed eventhandler then
- instance of the form will stay in the memory even form was closed
- and will work only until you tried using disposed controls again. If you will try to show disposed object then ObjectDisposedException will be thrown.
If you not using form anymore then Using block will be best method

Using a thread with designer objects vb.net

I have a big problem. I am currently designing an Antivirus, and it is coming along very well. But having all the scanning engines running on the same thread, I.E. the main one, is causing the app to lag in loading, and to become unresponsive during processes. I have tried implementing multithreading to increase the speed and overall performance of my application. But, every time that I try, i get the error of cross threading, I.E. I cannot use the form designers progress bars, buttons and labels etc. I just want to know why this error is thrown up, and how to fix it.
Thanks in Advance!
Use InvokeRequired to check which thread you are calling from, if you're not in the UI thread then InvokeRequired is True, and so you can invoke a delegate from the UI Thread to safely alter the Control:
Public Sub SetText(ByVal text As String)
If (Me.InvokeRequired) Then
'Invoke a delegate from the UI Thread
Me.Invoke(DirectCast(Sub() Label1.Text = "Test", MethodInvoker))
Else
Button1.Text = text
End If
End Sub
It is unsafe to call a control from a thread other than the one that created the control without using the Invoke method. Take a look at this example: http://msdn.microsoft.com/library/ms171728%28v=vs.110%29.aspx
Set your form property: CheckForIllegalCrossThreadCalls to false. The you are getting no errors any more.
Furthermore you must show, that you get a reference between your Thread and your form Controls. Otherwise you change the Controls of the Thread handled window (which you don't see).
Try to write Methods or Functions with By Ref parameter, to share your controls.

Difference form.Close() and form.hide()

What is the difference between form.Close() and form.Hide() in desktop application.
i know Form_Close event will not be fired in form.Hide() method what about other differences.
Is anyone faster?
form.Close() unloads the form from memory and makes it available to be garbage collected; you can no longer interact with the form in code.
form.Hide() just hides the form, but you can still interact with it in your code.
So it is not really a question of which one is faster, but rather "are you really done using this form or not"?
Hide makes the form invisible to the user. Close actually closes it and calls dispose on it.
From: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx
"When a form is closed, all resources created within the object are closed and the form is disposed. "
Hide only hides the form from the screen. Close is of course closes the form. If you want to get rid of the form that you don't want to use anymore then you should use Close. Hide and Close are different things.
Ditto the above... Typically the way you open the form determines which to use. If you use .Show() the calling code continues while the form is loaded and shown. If you use ShowDialog() then calling code stops while the form is loaded and shown. When you Hide the called form the calling code resumes to the next statement.
Here is a sample of the second case:
Dim frm As New frmSearch2
frm.inFormName = "frmFacility"
frm.ShowDialog(Me)
If frm.outPrimaryKey.Length > 0 Then
frmMain.Open_Form("frmFacility", frm.outPrimaryKey)
End If
frm.Close
frm = Nothing
outPrimaryKey is a form level Public variable. You can also address any of the controls on the form.

What is the purpose of calling Invoke from the specific control that's affected?

Say I've got the following sub that simply adds passed items to a ListView control:
Private Sub AddListItem(ByVal item As ListViewItem)
UIList.Items.Add(item)
End Sub
And I use that from a BackgroundWorker thread, like so:
UIList.BeginInvoke(Sub() AddListItem(lvItem))
Well quite by accident I've just discovered that it doesn't seem to matter which control is used to call the Invoke\BeginInvoke method, or even if I omit a control altogether and just call the method directly – which I assume just uses Me.<Method> behind the scenes – it doesn't seem to matter. The code still works.
So, is using the affected control to call the method just a way to make following the code easier? What, if any, are the other advantages? And are there certain pitfalls one needs to be aware of when using a different control?
Using ILSpy and digging down the Control.Invoke method, an excerpt is
...
UnsafeNativeMethods.PostMessage(
new HandleRef(this, this.Handle),
Control.threadCallbackMessage,
IntPtr.Zero,
IntPtr.Zero);
...
In addition, MSDN states:
The Invoke method searches up the control's parent chain until it
finds a control or form that has a window handle if the current
control's underlying window handle does not exist yet. If no
appropriate handle can be found, the Invoke method will throw an
exception. Exceptions that are raised during the call will be
propagated back to the caller.
So usually it shouldn't matter which control you post to.
Personally, I use the "nearest" control I can get to call the Invoke method.

What is the correct way to fully remove a control from a parent control/form?

I have a UI element in my application where a Panel is used to host one of several potential custom UserControls. The Panel itself is hosted in a standardised UserControl that I am using something like a non-modal dialog that I'm calling a 'pane'.
The method I use is to instantiate a new instance of the standard pane, then with logic instantiate one of the several optional hosted controls inside it using Panel.Controls.Add(control). I then add the new pane to the interface control in a set location, again with a Control.Controls.Add(control), followed by a control.BringToFront() to maximise its z position.
This all works well, however when the time comes to hide the pane and destroy it, I cannot seem to fully get rid of it. Originally I was simply using Control.Controls.Remove(control) and for good measure setting the pane's Parent property to Nothing. This would have the desired effect of making the pane disappear, and my assumption was that now the control was unreferenced, that GC would dispose of it.
What I am seeing however is that the control still blits instantaneously onto the screen when the next outer hosting TabControl changes tab page, implying it still exists somewhere. I can confirm that this is not a graphical issue and the pane object persists using the VS Watch window's 'Make Object ID'. (At least I think this is proof, that without a code-accessible reference I can still directly see the object and its properties continue to exist.)
I have tried replacing
Control.Controls.Remove(pane)
pane.Parent = Nothing
with
pane.Dispose()
GC.Collect()
where the Dispose call I can confirm both removes the control from its parent's Controls collection and sets its Parent property to Nothing, but appears to do no more. It persists after forced GC and still blits onscreen occasionally.
This all leads to my original question, what is the proper way to remove and fully destroy controls after they have served their purpose?
According to this article from MSDN it seems like you might be experiencing side affects from the object being on the finalization queue.
A Dispose method should call the GC.SuppressFinalize method for the object it is disposing. If the object is currently on the finalization queue, GC.SuppressFinalize prevents its Finalize method from being called.
Translation: The finalize method isn't being called, and so the resources associated with your control are not being released. After a bit more digging, I found that you should
Always call Dispose before you release your last reference to the Component. Otherwise, the resources it is using will not be freed until the garbage collector calls the Component object's Finalize method.
From this article.
So either you need to release your last reference OR you need to call the components finalize method directly so your GC.Collect() will work.