【问题标题】:Do something in the Background without freezing the Program在后台做某事而不冻结程序
【发布时间】:2019-08-13 00:28:02
【问题描述】:

在我的程序中,我有一个计时器,用于检查您是否已连接到互联网并检查您是否已连接到 VPN。代码比较简单

 Public Function IsInternetConnected() As Boolean
    If My.Computer.Network.Ping("google.com", 2000) Then
        Return True
    Else
        Return False
    End If
End Function
Public Function IsVPNConnected() As Boolean
    If My.Computer.Network.Ping("10.0.2.29", 2000) Then
        Return True
    Else
        Return False
    End If
End Function

问题是每次它检查程序都会挂起几秒钟,不会让你做任何其他事情。有没有一种方法可以在不冻结应用程序的情况下不断检查它?

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick

    If IsVPNConnected() = True Then
        BtnVPN.BackColor = Color.LightGreen
        BtnVPN.Text = "Connected"
    Else
        BtnVPN.BackColor = Color.Red
        BtnVPN.Text = "Disconnected"
    End If

    If IsInternetConnected() = True Then
        BtnInternet.BackColor = Color.LightGreen
        BtnInternet.Text = "Connected"
    Else
        BtnInternet.BackColor = Color.Red
        BtnInternet.Text = "Disconnected"
    End If

End Sub

【问题讨论】:

  • 计时器是 Windows 窗体计时器吗?显示计时器的代码。
  • 可能是 backgroundorker 或线程的工作,具体取决于您的用途。
  • 我添加了计时器的代码
  • 启动后台工作程序(并暂停计时器)的计时器,当后台工作程序完成时,它会更改按钮属性(并继续计时器)。你可以调查一下。
  • 你从哪里调用这个函数?

标签: vb.net


【解决方案1】:

您需要将您的函数放在后台工作程序中,然后在需要当前函数的功能时直接调用后台工作程序而不是函数。这将防止您的应用程序在函数运行时冻结。

它会是这样的:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    SyncLock internetconnected
        If My.Computer.Network.Ping("google.com", 2000) Then
            internetconnected = True
        Else
            internetconnected = False
        End If
    End SyncLock
End Sub

然后,当您希望后台工作人员执行以下操作时,您可以调用它:

BackgroundWorker1.RunWorkerAsync()

【讨论】:

  • 你应该给变量加一个锁。并确保您不会同时运行工作人员多次。还有为什么你把真假放在引号里?
  • 我刚写的很快。你是对的,它不应该有引号。
【解决方案2】:

ping 可能需要很长时间才能执行。也许尝试使用:System.Net.Dns.GetHostAddresses("www.google.com")

无论如何,正如其他人所说,您需要在新线程中运行您的检查代码。在这里查看答案:Create a new thread in VB.NET

【讨论】:

    【解决方案3】:

    我会摆脱计时器并改用任务。这里我已经在 Shown 事件中启动了任务。

    Private tmrTask As task
    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        tmrTask = Task.Run(Sub()
                               Do
                                   Me.BeginInvoke(Sub()
                                                      If IsVPNConnected() Then
                                                          BtnVPN.BackColor = Color.LightGreen
                                                          BtnVPN.Text = "Connected"
                                                      Else
                                                          BtnVPN.BackColor = Color.Red
                                                          BtnVPN.Text = "Disconnected"
                                                      End If
    
                                                      If IsInternetConnected() Then
                                                          BtnInternet.BackColor = Color.LightGreen
                                                          BtnInternet.Text = "Connected"
                                                      Else
                                                          BtnInternet.BackColor = Color.Red
                                                          BtnInternet.Text = "Disconnected"
                                                      End If
                                                  End Sub)
                                   '<<< adjust sleep
                                   Threading.Thread.Sleep(1000) '<<< this would be the same as interval from timer
                               Loop
                           End Sub)
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 2019-02-14
      • 1970-01-01
      • 2021-08-28
      • 2023-03-14
      • 1970-01-01
      • 2013-10-06
      相关资源
      最近更新 更多