Vb.net 如何在Do循环语句运行时保持窗体的响应性
如果运行以下代码,您将看到在运行Vb.net 如何在Do循环语句运行时保持窗体的响应性,vb.net,multithreading,winforms,Vb.net,Multithreading,Winforms,如果运行以下代码,您将看到在运行Do[…]循环语句时无法单击Button2: Imports Microsoft.Office.Interop Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim xlApp As New Excel.Application xlApp
Do[…]循环
语句时无法单击Button2
:
Imports Microsoft.Office.Interop
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
xlApp.Visible = True
Dim wb1 As Excel.Workbook
wb1 = xlApp.Workbooks.Open("C:\Book1.xlsx")
Dim wsSheet1 As Excel.Worksheet
wsSheet1 = CType(wb1.Sheets(1), Excel.Worksheet)
Do
wsSheet1.Cells.Copy()
wsSheet1.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
Loop
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
MsgBox("Hello")
End Sub
End Class
当
do[…]循环
语句运行时,如何保持Form1
的响应性?根据我所读的内容,当您要求您的程序执行特定任务时,您的UI似乎变得没有响应。在这种情况下,您应该查看msdn上的后台工作程序示例,或者您可以使用其他线程而不使用后台工作程序,这真的是你的选择。
下面是我写的一个快速示例,它将使用不同的线程在屏幕上随机位置绘制矩形框,这将允许您在窗口绘制到屏幕时移动窗口,并与其他组件进行交互,使它们在不冻结的情况下正常工作,例如消息框
Imports System.ComponentModel
Public Class Form1
Dim random0 As New Random
Dim thread0 As New Threading.Thread(New Threading.ThreadStart(AddressOf threadDrawing0))
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
thread0.Start()
End Sub
Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
thread0.Abort()
End Sub
Private Sub threadDrawing0()
For i = 0 To 1000
System.Threading.Thread.Sleep(100)
Me.CreateGraphics().DrawRectangle(New Pen(Brushes.Blue, 4), New Rectangle(random0.Next(0, Me.Width), random0.Next(0, Me.Height), 20, 20))
Next
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
MessageBox.Show("Hello World")
End Sub
End Class
由于我没有您正在使用的excel文件,我无法根据您的具体需要测试代码,但是这应该会让您真正走上正确的道路。
MSDN后台工作人员链接:,以便在执行[…]操作时保持表单的响应性循环
语句正在运行,您需要使用类在单独的线程上运行它
首先创建一个新方法,并将Do[…]循环
语句放在该方法中:
Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)
Do
worksheet.Cells.Copy()
worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
Loop
End Sub
然后,您可以使用以下方法调用此方法:
我也不再使用MsgBox
,而是使用MessageBox.Show
MsgBox
适用于VB6,并最终授权给MessageBox
,因此使用MessageBox是有意义的。Show
:
MessageBox.Show("Hello")
总的来说,您的代码看起来与此类似:
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
xlApp.Visible = True
Dim wb1 As Excel.Workbook
wb1 = xlApp.Workbooks.Open("C:\Book1.xlsx")
Dim wsSheet1 As Excel.Worksheet
wsSheet1 = CType(wb1.Sheets(1), Excel.Worksheet)
Task.Factory.StartNew(Sub() CopyCells(wsSheet1))
End Sub
Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)
Do
worksheet.Cells.Copy()
worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
Loop
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
MessageBox.Show("Hello")
End Sub
End Class
请注意,您必须导入System.Threading.Tasks
才能使用Task
类
如果您希望UI在长时间运行的任务中具有响应性,则必须使用辅助线程。这可以通过多种方式完成,包括使用任务
类。不幸的是,这不是编码服务。你需要自己尝试一下,然后如果你有问题,有人会帮助你解决。
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim xlApp As New Excel.Application
xlApp.Visible = True
Dim wb1 As Excel.Workbook
wb1 = xlApp.Workbooks.Open("C:\Book1.xlsx")
Dim wsSheet1 As Excel.Worksheet
wsSheet1 = CType(wb1.Sheets(1), Excel.Worksheet)
Task.Factory.StartNew(Sub() CopyCells(wsSheet1))
End Sub
Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)
Do
worksheet.Cells.Copy()
worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
Loop
End Sub
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
MessageBox.Show("Hello")
End Sub
End Class