2

I have written a server program that does a lot of jobs in threads simultaneously.

In those threads, I have to update a ListView with status information, but as it is right now using invoke, the thread waits for the UI to finish updating the ListView.

Any good advice to how I can send the status to the ListView and continue the thread while ListView finish updating?

Here's my code...

Public Delegate Sub InfoDelegate(status As String)

Public Sub Info(status As String)
    If Me.InvokeRequired Then
        Dim d As New InfoDelegate(AddressOf Info)
        Me.Invoke(d, status)
    Else
        Dim item As New ListViewItem With {
            .Text = status}

        With lv
            .BeginUpdate()
            .Items.Insert(0, item)
            If .Items.Count > 500 Then
                For i As Integer = Me.lv.Items.Count - 1 To 500 Step -1
                    Me.lv.Items.RemoveAt(i)
                Next
            End If
            .EndUpdate()
        End With
    End If
End Sub
8
  • Use BeginInvoke instead. Commented Dec 17, 2016 at 9:41
  • Remember that you must call EndInvoke too! Commented Dec 17, 2016 at 9:53
  • @VisualVincent are you sure? Microsoft doesn't call EndInvoke ... msdn.microsoft.com/en-us/library/a06c0dc2(v=vs.110).aspx Commented Dec 17, 2016 at 9:55
  • Yes: "No matter which technique you use, always call EndInvoke to complete your asynchronous call." - msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx Commented Dec 17, 2016 at 9:57
  • And I am also certain because I know that from experience. -- What you can do to avoid blocking your thread is calling EndInvoke in a method executed on the UI thread. Commented Dec 17, 2016 at 9:58

1 Answer 1

2

You can call Control.BeginInvoke() to invoke the method asynchronously. However that call needs to be followed by a EndInvoke() call, or else you will get memory and/or thread leaks.

In the .NET Framework versions 4.0 and up you can utilize lambda expressions to pass the IAsyncResult returned from the BeginInvoke call to the lambda expression itself. Thus, you can call EndInvoke without having it block since by the time that it is called the asynchronous operation is already finished.

Here's an example:

Dim iar As IAsyncResult = _
    Me.BeginInvoke(Sub()
                                   Info("Status here") 'Calling your Info() method.
                                   Me.EndInvoke(iar)
                               End Sub)
Sign up to request clarification or add additional context in comments.

9 Comments

@MojoDK : No problem, glad I could help!
I believe that you're wrong about having to call EndInvoke. This is from MSDN: "You can call EndInvoke to retrieve the return value from the delegate, if neccesary, but this is not required. EndInvoke will block until the return value can be retrieved". So, you CAN call EndInvoke to get the return value from an invoked function but you don't HAVE to otherwise.
@jmcilhinney : Then what about: "No matter which technique you use, always call EndInvoke to complete your asynchronous call"? It's from the MSDN too: msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx
@jmcilhinney : And from my experience you need to call EndInvoke. I've experienced problems such as the UI freezing when too many BeginInvoke calls were called without being followed by EndInvoke.
@jmcilhinney Is correct and I agree. Personally I have never seen any issues not calling EndInvoke. Specifically if using a delegate it's blocked anyways and won't return to the caller until it's finished. Calling EndInvoke at this point doesn't matter. In the example you provided It doesn't matter either because when that method is called, it's immediately blocked until it's done and then comes back to the caller, calling EndInvoke is irrelevant at this point....
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.