Asynchronous events

I am writing an application that works simultaneously with multiple threads. Each thread negotiates with a web server and loads different amounts of data. I would like to show the overall progress for all threads in the application.

Each thread raises an event loaded through 1 megabyte:

 RaiseEvent My_Event(Size_Downloaded as double,Total_Size as double)

Is there a way to display the total number of cross-streams loaded into the main form without error?

It does not have to be instantaneous, so can a timer work?

+4
source share
3 answers

You can change the event signature and add a stream identifier and use a timer to display the overall display.

Dim _info As New ConcurrentDictionary(Of Integer, DLoadInfo)

Sub MyEvent(id As Long, Size_Downloaded As Double, Total_Size As Double)

    Dim v = New DLoadInfo() With 
        {
            .SizeDownloaded = Size_Downloaded, 
            .TotalSize = Total_Size
        }

    _info.AddOrUpdate(id, v,
            Function(key, oldValue)
                Return v
            End Function
         )
End Sub

Private Sub TimerDisplay_Tick(sender As Object, e As EventArgs)
    Dim sizeDownloaded, totalSize As double
    For Each o As DLoadInfo In _info.Values
        sizeDownloaded += o.SizeDownloaded
        totalSize += o.TotalSize
    Next
    TextBoxSizeDownloaded.Text = sizeDownloaded 
    TextBoxTotalSize.Text = totalSize 
End Sub

Class DLoadInfo
    Public property SizeDownloaded As Double
    Public property TotalSize As Double
End Class
+3
source

, , . - UI-, , imo - .

:

.

Private Sub DoThis()
    Dim bgw As New BackgroundWorker
    AddHandler bgw.DoWork, AddressOf bgwDoWork
    AddHandler bgw.RunWorkerCompleted, AddressOf bgwDone

    bgw.RunWorkerAsync(1)

End Sub
Private Sub bgwDoWork(sender As Object, e As DoWorkEventArgs)
    Dim i As Integer = e.Argument
    RTB.AppendText(CInt(i + 2).ToString)
End Sub

, sub, :

Private Sub DoThis()
    Dim bgw As New BackgroundWorker
    AddHandler bgw.DoWork, AddressOf bgwDoWork
    AddHandler bgw.RunWorkerCompleted, AddressOf bgwDone

    bgw.RunWorkerAsync(1)

End Sub

Private Delegate Sub UpdateText(item As String)
Private Sub Update_RTB(item As String)
    If RTB.InvokeRequired Then
        RTB.Invoke(New UpdateText(AddressOf Update_RTB), item)
    Else
        RTB.AppendText(item)
    End If
End Sub

Private Sub bgwDoWork(sender As Object, e As DoWorkEventArgs)
    Dim i As Integer = e.Argument
    Update_RTB(CInt(i + 2).ToString)
End Sub

, , , .

.

+3

, :

Private Sub ThreadSafeRaise_MyEvent(Size_Downloaded As Double, Total_Size As Double)
    If Me.InvokeRequired = True Then
        Me.Invoke(Sub() ThreadSafeRaise_MyEvent(Size_Downloaded, Total_Size))
    Else
        RaiseEvent My_Event(Size_Downloaded, Total_Size)
    End If
End Sub

( Me ), lambda , . , , .

, ( < >):

ThreadSafeRaise_MyEvent(<size downloaded here>, <total size here>)

And this! There is no need for an additional call, so your event will be thread safe. You also do not need to declare your delegates, since lambda (expression Sub()) does this for you.

Hope this helps!

+2
source

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


All Articles