|
-
Oct 6th, 2011, 07:38 AM
#1
Thread Starter
New Member
[RESOLVED] Delegate Function
Hello, I've been searching through google and here and cannot find a solution my problem. I hope everyone can help me with this problem.
I have a program that has a main form. This main form has other components that has their own background worker thread too but is separate from the main form. Everything is fine, however the main thread listens to an event when the event is fired by one of the component it start a background process (BackgroundWorker) to show a form dialog for user input. The main thread must continue to work and show the progress from other components it has and show the form dialog to get the user input. The code below works fine but the GetParentFromUIThread() keeps returning nothing if I use BeginInvoke() but if I use Invoke() I get a Cross-thread operation not valid error, thanks in advance for any help.
Code:
Private Delegate Function DelGetParent() As Form
Private Function GetParentFromUIThread() As Form
Dim refParentObject As Form = Nothing
If Me.InvokeRequired Then
refParentObject = DirectCast(Me.Invoke(New DelGetParent(AddressOf GetParentFromUIThread)), Form)
'Me.BeginInvoke(New DelGetParent(AddressOf GetParentFromUIThread))
Else
refParentObject = Me
End If
Return refParentObject
End Function
Private Sub _NewMaterial_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles _NewMaterial.DoWork
Dim rMaterial As New frmMaterials(_Job)
rMaterial.EnableCancelButton(False)
rMaterial.Owner = GetParentFromUIThread()
rMaterial.ShowDialog()
rMaterial.Dispose()
End Sub
Last edited by MLVB6; Oct 7th, 2011 at 07:46 AM.
Reason: RESOLVED
-
Oct 6th, 2011, 04:37 PM
#2
PowerPoster
Re: Delegate Function
when using Invoke, you need to make sure that you access the control to the correct thread it was created from.
its not entirely clear really what you are trying to achieve or do here or what the purpose of your application here is.
your main form can still continue to run - just dont use ShowDialog() which is thread blocking but instead just do Show()
there is no need to spin up another thread JUST to show a form.... thats expensive and inefficient and incorrect way to use threading
-
Oct 7th, 2011, 07:44 AM
#3
Thread Starter
New Member
Re: Delegate Function
Thanks for replying Techno. The purpose of the ShowDialog() instead of Show() is to force the user to input data or force the user to make a decision from the dialog. If I just call show() from the main form then it will lock up/pause that thread until the ShowDialog() is closed.
By opening the form in a new thread with ShowDialog() it will force the user to make or enter some type of data before returning back to the main form thread. But the problem is it will not reference the parent form as the owner of the new form dialog because it was created on a different thread.
I've found a solution to the problem. It's not exactly what i want but it works too. Here is the solution for someone who may need it in the future.
Code:
Private _MaterialBgWorker as BackgroundWorker
Private _Material As frmMaterials
' In your form load event add
_MaterialBgWorker = new BackgroundWorker
' In the subroutine that you use to call the new form or the subroutine event handler add the following
If _MaterialBgWorker.IsBusy = False And _Material Is Nothing Then _MaterialBgWorker.RunWorkerAsync()
' Lastly add the following subroutine
Private Sub ShowMaterialEntry()
If Me.InvokeRequired Then
Me.BeginInvoke(New Action(AddressOf ShowMaterialEntry))
Else
If _Material Is Nothing Then _Material = New frmMaterials(_Job)
_Material.Owner = Me
_Material.StartPosition = Windows.Forms.FormStartPosition.CenterParent
_Material.ShowDialog()
_Material.Dispose()
_Material = Nothing
GC.Collect()
End If
End Sub
-
Oct 7th, 2011, 07:59 AM
#4
PowerPoster
Re: [RESOLVED] Delegate Function
it is best practice to NOT invoke the GC, it can cause some undeserible or unexpected behaviors. you should let the GC do its job in the background. Furthermore there is no guarentee the GC will be invoked there and then.
Eventually, the GC class may well be removed from .NET and left out of reach for developers.
The other, and more recommended way in this scenario, thing to do is to hide your other form when you call Show() on this new form. Then when done... raise an event back to the other form so it displays.
-
Oct 7th, 2011, 08:27 AM
#5
Thread Starter
New Member
Re: [RESOLVED] Delegate Function
Yes understand what you are saying and tried not to use but there are cases where GC may need to be call. In my case it needs to be call to release some memory as the program will be running on an older computer with low memory.
As for the Hide() and Show() methods, it does not work for my situation as Show() will allow the user to click the main form and lose focus on the new form.
-
Oct 7th, 2011, 08:42 AM
#6
PowerPoster
Re: [RESOLVED] Delegate Function
think you mis understood what I was saying:
when you call Show(), just before it - hide the form that you are calling Show() FROM, to prevent the user from clicking on the form or maybe not enable it (me.Enabled = false)
as for the GC again, irrespective of memory on the system, let the GC handle it. let the .NET Framework runtime handle the memory usage. it will be fine.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|