我有以下代码:
Public Class Form1
Dim ping As New Ping
Dim replyeuw As PingReply
Dim euwthread As Thread
Dim num As Integer = 0
Dim pingms As Integer
Public Sub pingareuw()
If My.Computer.Network.IsAvailable Then
replyeuw = ping.Send("prod.euw1.lol.riotgames.com")
pingms = replyeuw.RoundtripTime
If replyeuw.Status = IPStatus.Success Then
FlatLabel3.Text = "EUW PING: " & pingms
Else
FlatLabel3.Text = "Nope..."
End If
Thread.Sleep(500)
Else
MsgBox("Liga a net pah!")
End If
End Sub
Private Sub FormSkin1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
euwthread = New Thread(AddressOf Me.pingareuw)
euwthread.Start()
End Sub
我收到了这个错误:
跨线程操作无效:控制从另一个线程访问的“FlatLabel3”。
为什么?
答案 0 :(得分:0)
除了创建它的线程(通常是应用程序的主线程)之外,您不能从Control
修改Thread
。相反,您可以使用BackgroundWorker。
Private bw As BackgroundWorker
Private Sub FormSkin1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' create a new Backgroundworker and start it
bw = New BackgroundWorker
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub bg_DoWork(sender As Object, args As DoWorkEventArgs) _
Handles bg.DoWork
If My.Computer.Network.IsAvailable Then
replyeuw = ping.Send("prod.euw1.lol.riotgames.com")
pingms = replyeuw.RoundtripTime
If replyeuw.Status = IPStatus.Success Then
bg.ReportProgress(0, "EUW PING: " & pingms)
Else
bg.ReportProgress(0, "Nope...")
End If
Thread.Sleep(500)
Else
MsgBox("Liga a net pah!")
End If
End Sub
Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles bg.ProgressChanged
' you can access the control here
FlatLabel3.Text = e.ToString()
End Sub
答案 1 :(得分:0)
通常,您的表单应用程序被标记为“StaThread”。这意味着“单线程公寓”,这是古老的COM时代的语言。你的表单和它上面的控件都存在于相信中,它们永远不会被任何其他线程作为它们创建的线程调用。
要解决您的问题,您需要在函数中使用函数“InvokeRequired”,这些函数是从另一个线程调用的。
这样做的基本方案是(对不起几乎 - c#语法 - 在VB中相同):
void MaybeCalledFromOtherThread()
{
if( this.InvokeRequired )
return this.Invoke(MaybeCalledFromOtherThread) // not exact syntax for Invoke
// code below only executed from the correct thread.
}
因此,在您的情况下,您最好将一个成员函数添加到您的Forms类,如UpdatePingDisplay(string newText)
,并使用上面显示的技巧。从您的线程中,您可以通过调用新函数替换标签上的那些直接操作,并且所有操作都应该有效。