Results 1 to 6 of 6

Thread: [RESOLVED] Delegate Function

  1. #1

    Thread Starter
    New Member
    Join Date
    Nov 2005
    Posts
    11

    [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

  2. #2
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    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

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  3. #3

    Thread Starter
    New Member
    Join Date
    Nov 2005
    Posts
    11

    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

  4. #4
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    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.

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

  5. #5

    Thread Starter
    New Member
    Join Date
    Nov 2005
    Posts
    11

    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.

  6. #6
    PowerPoster
    Join Date
    Aug 2003
    Location
    Edinburgh, UK
    Posts
    2,773

    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.

    MVP 2007-2010 any chance of a regain?
    Professional Software Developer and Infrastructure Engineer.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width