vb.net调用问题

我有一个运行后台作业的线程,需要偶尔更新GUI.我的程序设计为当用户单击表单时,线程和后台操作仍然运行,但控件已被处理(用于内存管理).

我一直在使用Invoke()和“If Control.Created = True”来确保线程可以成功更新控件而不会遇到任何异常.但是,重新创建表单时,所有“Control.Created”值都为false,并且Invoke()失败,并且在创建窗口句柄之前,无法在控件上调用“{”Invoke或BeginInvoke.“}”

我的猜测是,这与以下事实有关:当重新创建表单时,它被分配了不同的句柄,而“Invoke()”正在查看旧句柄.所以我的问题是,我该如何解决这个问题?

编辑:根据要求,打开表单的代码和bg线程的工作位置

打开DropLogMDIalt表单很简单

    FormCTRL.Show()

修改控件后运行后台线程,以便NumericUpDown大于0(以便有倒计时的东西)

    Private Sub NLauncherTerminateInput_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DLScanInterval.ValueChanged
    If DLScanInterval.Created = True Then
        DLTimerControlValue = DLScanInterval.Value
        If DLTimerControlValue = 0 Then
            CancelDropLogTimer()
        Else
            If DLScanIntervalControl.Active = False Then
                BeginDropLogTimer()
            End If
        End If
    End If
End Sub


Public Sub BeginDropLogTimer()
    Dim N As New Threading.Thread(AddressOf DropLogTimerIntervalThreadWorker)
    N.Start()
    DLScanIntervalControl.ThreadID = N.ManagedThreadId
    DLScanIntervalControl.Active = True
End Sub

Public Sub CancelDropLogTimer()
    DLScanIntervalControl.Active = False
End Sub

    Public Sub DropLogTimerIntervalThreadWorker()
    DLScanTimerSecondsLeft = DLTimerControlValue * 60
    Dim s As Integer = DLTimerControlValue
    Do Until 1 = 2
        DLScanTimerSecondsLeft = DLTimerControlValue * 60
        Do Until DLScanTimerSecondsLeft <= 0
            If Not (DLTimerControlValue = 0 Or DLScanIntervalControl.CancelPending = True) Then
            Else
                Exit Sub
            End If

            If Not DLTimerControlValue = s Then
                DLScanTimerSecondsLeft = DLTimerControlValue * 60
                s = DLTimerControlValue
            End If

            Dim ToInvoke As New MethodInvoker(Sub()
                                                  Timer(DLScanTimerSecondsLeft, ":", DLScanIntervalTB)
                                              End Sub)
            If (Me.IsHandleCreated) Then
                If (InvokeRequired) Then
                    Invoke(ToInvoke)
                Else
                    ToInvoke()
                End If
            End If


            Threading.Thread.Sleep(1000)
            DLScanTimerSecondsLeft -= 1
        Loop

        CompareScan = True
        PerformScan()
    Loop
End Sub

通过声明一个新的thread.thread简单地调用该线程,但是,我已经创建了一个类和一个变量,线程用它来检查它是否应该仍在运行(类似于后台工作者的方式)这是由“DLScanIntervalControl.CancelPending”

然后,表格将被关闭

Form.Close()

如果用户单击标签然后使用与上面所示相同的方法(FormCTRL.Show()),则可以重新打开它

最佳答案 从
MSDN开始:

“If the control’s handle does not yet exist, InvokeRequired searches up the control’s parent chain until it finds a control or form that does have a window handle. If no appropriate handle can be found, the InvokeRequired method returns false.”

换句话说,您需要验证是否已创建句柄,然后检查是否需要调用.

If(Me.IsHandleCreated) Then
    If(Me.InvokeRequired) Then
        '...
    Else
        '...
    End If
End If
点赞