我有一个运行后台作业的线程,需要偶尔更新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