代码为 运行 期间无法单击 Form1 的叉号

Can not click cross sign of Form1 during code is running

1- 制作 Windows 表格申请。

2- 将 Button1 放到 Form1 上。

3- 运行 以下代码。

Public Class Form1    
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs)Handles Button1.Click
    For i = 1 To 10000000000
        i = i + 1
    Next
End Sub
End Class

4- 虽然上面的代码是 运行 尝试单击 Form1 的叉号。 (看到上面的代码是运行,你不能点击Form1的叉号)

问题:为什么代码为运行时无法点击Form1的叉号?

用户如何停止 运行 应用程序而不等待它完成?

您无法单击 X 按钮,因为您的主 UI 线程正忙于执行大循环操作。等待,完成后您可以关闭表格。

否则,您可以重构您的代码并在一个方法中提取循环信息,然后 运行 它完全使用一个单独的线程。在这种情况下,您的主 UI 线程将不会被阻塞。

这里有两个选择

快(但不好)而且好

这是快速选项

Public Class Form1    
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs)Handles Button1.Click
For i = 1 To 10000000000
   application.doevents 
   i = i + 1
Next
End Sub
End Class

更好的选择是使用后台工作者或线程

Public Class Form1    
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs)Handles Button1.Click
  Dim tThread as new threading.thread(addressof DoCount)
  tThread.start
End Sub

Private Sub DoCount()
  For i = 1 To 10000000000
   i = i + 1
  Next

End Sub
End Class

要么处理这个简单的示例,但当事情变得复杂时,您确实需要了解发生了什么。您可能还想查看 Backgroundworker 这是一个很好的起点 https://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

您正在 运行 在 UI 线程中循环并且 UI 线程太忙而无法响应,因为您使用的是 .Net 4.0 并且您可以'如果不使用 async/await 模式,您可以使用线程或 BackgroundWorker.

执行此类耗时操作

示例 - 使用 BackgroundWorker

在您的表单上放置一个 BackGroundWorker 组件,并将这些代码写入 DoWork 事件处理程序。请注意 DoWork 中的代码将 运行 在不同的线程上,你不能直接到 UI,你应该使用 Invoke.

Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Me.BackgroundWorker1.RunWorkerAsync()
    MessageBox.Show("The code immediately run")
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim sum As Integer = 0
    For index = 1 To Int32.MaxValue - 1
        sum += 1
    Next
    Me.Invoke(New Action(Sub()
                             Me.Text = ("Result: " & sum.ToString())
                         End Sub))
End Sub

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, the BackgroundWorker class provides a convenient solution.