异步事件被触发
我在写一个应用程序,它有多个线程同时运行。每个线程都会与网络服务器通信并下载不同数量的数据。 我想显示应用程序中所有线程的总进度。异步事件被触发
每个线程引发一个事件,每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语法,所以我没有用完整的代码示例回答)。 –