如果您运行以下代码,您将看到在Button2
语句正在运行时无法单击Do[...]Loop
:
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
在Form1
语句运行时如何保持Do[...]Loop
响应?
答案 0 :(得分:1)
根据我的阅读,当您要求程序执行特定任务时,听起来您的UI变得反应迟钝了
在这种情况下,您应该查看Background Worker
示例在msdn或你可以使用另一个线程而不使用后台工作者,它真的是你的选择。
这是我写的一个快速示例,它将使用一个随机位置将矩形框绘制到屏幕上不同的线程,这将允许您在绘制到屏幕时移动窗口并与其他组件交互,让它们正常工作而不会冻结,如MessageBox
。
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背景工人链接:https://msdn.microsoft.com/es-es/library/cc221403(v=vs.95).aspx
答案 1 :(得分:0)
为了在Do[...]Loop
语句运行时保持表单响应,您需要使用Task类在单独的线程上运行它。
首先创建一个新方法并将Do[...]Loop
语句放在该方法中:
Private Sub CopyCells(ByVal worksheet As Excel.Worksheet)
Do
worksheet.Cells.Copy()
worksheet.Cells.PasteSpecial(Paste:=Excel.XlPasteType.xlPasteValues)
Loop
End Sub
然后,您可以使用Task.Factory.StartNew调用此方法:
Task.Factory.StartNew(Sub() CopyCells(wsSheet1))
我也会放弃使用MsgBox
并使用MessageBox.Show
。 VB6存在MsgBox
,无论如何最终委托给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
类。