我想在foreach循环中更新标签。
问题是:程序一直等到循环完成然后更新标签。
是否可以在foreach循环期间更新标签?
代码:
Dim count as Integer = 0
For Each sFile as String in Files
'ftp-code here, works well
count = count+1
progressbar1.value = count
label1.text = "File " & count & " of 10 uploaded."
next
提前致谢
答案 0 :(得分:2)
标签未更新,因为在执行foreach
循环时UI线程被阻止
您可以使用async-await
方法
Private Async Sub Button_Click(sender As Object, e As EventArgs)
Dim count as Integer = 0
For Each sFile as String in Files
'ftp-code here, works well
count = count+1
progressbar1.value = count
label1.text = "File " & count & " of 10 uploaded."
Await Task.Delay(100)
Next
End Sub
因为您将使用Ftp连接,这是使用async-await
的完美候选者。
Await
行将释放UI线程,该线程将使用新值更新label,并在100毫秒后从该行继续。
如果您将异步代码用于ftp连接,那么您不需要Task.Delay
答案 1 :(得分:0)
您已经接受了答案,但作为替代方案,BackgroundWorker也可以用于此类事情。在我的情况下,用于获取原始文件的FTP发生得非常快,因此DoWork事件的这个片段用于将这些文件下载到打印机。
Dim cnt As Integer = docs.Count
Dim i As Integer = 1
For Each d As String In docs
bgwTest.ReportProgress(BGW_State.S2_UpdStat, "Downloading file " & i.ToString & " of " & cnt.ToString)
Dim fs As New IO.FileStream(My.Application.Info.DirectoryPath & "\labels\" & d, IO.FileMode.Open)
Dim br As New IO.BinaryReader(fs)
Dim bytes() As Byte = br.ReadBytes(CInt(br.BaseStream.Length))
br.Close()
fs.Close()
For x = 0 To numPorts - 1
If Port(x).IsOpen = True Then
Port(x).Write(bytes, 0, bytes.Length)
End If
Next
If bytes.Length > 2400 Then
'these sleeps are because it is only 1-way comm to printer so I have no idea when printer is ready for next file
System.Threading.Thread.Sleep(20000)
Else
System.Threading.Thread.Sleep(5000)
End If
i = i + 1
Next
在ReportProgress事件中......(当然,您需要将WorkerReportsProgress属性设置为True)
Private Sub bgwTest_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwTest.ProgressChanged
Select Case e.ProgressPercentage
'BGW_State is just a simple enum for the state,
'which determines which UI controls I need to use.
'Clearly I copy/pasted from a program that had 15 "states" :)
Case BGW_State.S2_UpdStat
Dim s As String = CType(e.UserState, String)
lblStatus.Text = s
lblStatus.Refresh()
Case BGW_State.S15_ShowMessage
Dim s As String = CType(e.UserState, String)
MessageBox.Show(s)
End Select
End Sub
答案 2 :(得分:-1)
使用Application.DoEvents()是不够的?这清除了构建,您应该能够非常快速地看到文本字段的更新。