我在寫一個應用程序,它有多個線程同時運行。每個線程都會與網絡服務器通信並下載不同數量的數據。 我想顯示應用程序中所有線程的總進度。異步事件被觸發
每個線程引發一個事件,每1兆下載:
RaiseEvent My_Event(Size_Downloaded as double,Total_Size as double)
有顯示沒有得到橫紗誤差的主要形式下載的總的方法嗎?
它不必是瞬間的,所以計時器可能工作?
我在寫一個應用程序,它有多個線程同時運行。每個線程都會與網絡服務器通信並下載不同數量的數據。 我想顯示應用程序中所有線程的總進度。異步事件被觸發
每個線程引發一個事件,每1兆下載:
RaiseEvent My_Event(Size_Downloaded as double,Total_Size as double)
有顯示沒有得到橫紗誤差的主要形式下載的總的方法嗎?
它不必是瞬間的,所以計時器可能工作?
你可以改變事件的簽名,並添加主題 的ID,並使用計時器來顯示顯示總
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
這工作完全謝謝 –
正如Rene所說,取決於你得到什麼跨線程錯誤。如果您遇到任何跨線程UI調用錯誤,那麼處理它的最好方法是通過代理。
剛剛撰寫了這一個真的很快爲例:
這將導致一個跨線程UI錯誤。
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
然而,委託子,我們就可以在主線程訪問控制:
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
不要猶豫,讓我知道如果你需要我的任何進一步澄清這一點。
乾杯。
謝謝你會嘗試這個明天 –
這是一個相當簡單的解決方案,我用多線程事件:
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>)
就是這樣!不需要進一步的調用,以這種方式提升事件是線程安全的。您也不需要聲明自己的任何代表,因爲lambda(Sub()
表達式)可以爲您做。
希望這會有所幫助!
沒有代碼,這個問題有點寬泛。你的意思是什麼樣的「跨線程錯誤」?跨線程UI調用?您可以通過使用[Control.Invoke]來避免它們(https://msdn.microsoft.com/de-de/library/a1hetckb%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang= vb#code-snippet-2)在事件處理程序中。 (我不習慣vb語法,所以我沒有用完整的代碼示例回答)。 –