Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 避免对话框暂停执行的多线程解决方案_Vb.net_Multithreading_Automation - Fatal编程技术网

Vb.net 避免对话框暂停执行的多线程解决方案

Vb.net 避免对话框暂停执行的多线程解决方案,vb.net,multithreading,automation,Vb.net,Multithreading,Automation,我目前正在VB.NET控制台应用程序中自动执行对库的一系列调用。函数调用通常需要一系列用户选择的输入。我的问题是,这些函数的集合创建了一个编程上不可访问的DialogBox实例,并暂停程序的执行,直到与它们交互为止 现在,我已经尝试根据下面的代码使用多个线程来解决这个问题 Public Sub StartFormFunction(ByVal inputValue As String) frameWork.showHiddenDialogBox(inputValue) End Sub

我目前正在VB.NET控制台应用程序中自动执行对库的一系列调用。函数调用通常需要一系列用户选择的输入。我的问题是,这些函数的集合创建了一个编程上不可访问的DialogBox实例,并暂停程序的执行,直到与它们交互为止

现在,我已经尝试根据下面的代码使用多个线程来解决这个问题

Public Sub StartFormFunction(ByVal inputValue As String)
       frameWork.showHiddenDialogBox(inputValue)
End Sub

Public Sub threadFunction(ByValue inputValue As String)
    Dim nrOfOpenForms As Integer = Application.OpenForms.Count()       
    Try               
        Dim t As New Thread(New ParameterizedThreadStart(AddressOf StartFormFunction))
        t.Priority = Threading.ThreadPriority.Highest
        t.Start(inputValue)
        'Wait until the prompt has been created.            
        While (Application.OpenForms.Count() = nrOfOpenForms) And (t.IsAlive)
        End While        
        if Not t.IsAlive Then
            log.Error("Thread did not open dialogBox")
            Return
        End If
        'Select preffered button on dialogBox
        Dim isFinished As Boolean = False
        For Each curForm As Form In Application.OpenForms
            For Each btn As Button In curForm.Controls.OfType(Of Button)
                If btn.Name = "Button3" Then
                    btn.PerformClick()
                    isFinished = True
                Exit For
            End If
            Next
            if isFinished Then
                Exit For
            End If
        Next
        'Wait until thread completed Function
        While t.IsAlive
        End While

        Catch ex As Exception        
            log.Error("Thread Error")
        End Try
End Sub
我还没有找到在控制台应用程序中使用Control.Invoke()的方法,正因为如此,才没有使用它。 使代码能够完全执行的方法是禁用我试图避免的
CheckForIllegalCrossThreadCalls

不使用多个线程就可以解决访问对话框的问题吗?如果不是,那么通过调用子调用是否可以解决问题

编辑 我的一些描述可能缺少详细的信息。 我的问题是,我的应用程序运行一个方法
showHiddenDialogBox()
,该方法在一个类中运行一组指令,该类不在我的代码范围内。当所有功能都已执行时,此不可访问类将显示一个窗体。显示此表单时,应用程序将暂停所有代码的执行,直到用户升级输入。 这就需要使用多个线程来进行访问。但是,当表单显示为所有内容时,此新线程将拥有该表单。这包括在我需要其他线程访问的按钮中。

不要使用“CheckForIllegalCrossThreadCalls”,只需使用以下代码调用控件:

'Insert this in a module
<Runtime.CompilerServices.Extension()>
Public Sub InvokeCustom(ByVal Control As Control, ByVal Action As Action)
    If Control.InvokeRequired Then Control.Invoke(New MethodInvoker(Sub() Action()), Nothing) Else Action.Invoke()
End Sub

你的问题缺乏信息。
frameWork.showHiddenDialogBox(inputValue)
做什么?什么时候需要调用?我没有看到任何需要调用的多线程代码。-您说要打开一个表单,但不让它阻止执行,因此您可能调用的是
form.ShowDialog()
,而不是
form.Show()
。很抱歉,没有提供详细信息。ShowHiddenDialogBox是一个向我无法访问的类提交一系列更改的方法。此方法执行操作并在最后显示一个messagebox,它将中断代码的执行,直到单击按钮为止。这是一个表单实例,不在我的范围内,无法访问。我现在的目标是使用一个线程来执行这个方法,当表单出现时,另一个线程正在提交一个输入以关闭表单并释放线程时,该线程可以被“锁定”。这是一个很难解决的问题,您需要做的是为每个btn循环调用整个
。使用Tyler的代码,但只调用当前表单,并在多行
Sub()
中执行您的操作。这将是一个很好的解决方案,如果我正确理解了方法,这将有冻结应用程序的问题。为了能够遍历表单按钮,我们需要一个表单的活动实例。要拥有表单的活动实例,我们需要有一个单独的线程来创建表单,或者锁定当前线程来阻止我们进行迭代。但是您已经在迭代表单的按钮了,在那里添加调用有什么问题(这就是我的意思)?您的应用程序已被
For
-循环阻止。如果您不想阻止它,请启动另一个线程。@VisualIncent正如您所看到的
Control.Invoke(Action)
已在子线程中,需要检查是否为调用。对于多控件,您是对的,但我对包含面板或TableLayout的窗体有问题。对于速度。。。取决于他有多少个控件,如果corse的控件超过10个(同时),则最好调用一个表单,但如果有2个或3个。。为什么要调用一个完整的表单?(重写我的注释,使其听起来不那么刺耳)我可以问一下,当您可以调用
控件时,为什么要创建
方法调用器
委托和lambda表达式方法来调用操作?此外,如果他同时更新多个UI元素,最好调用
Form.InvokeCustom
并在内部使用多行lambda,而不是调用每个控件,因为每个调用都需要一些时间来执行。
但是如果有2个或3个。。为什么要调用一个完整的表单?
-
控件.invoke()
方法将查找父表单并无论如何调用它。唯一的时差是找到绝对父级所需的时间,因为调用只会将消息放入UI线程队列(所有控件和窗体都在其中运行)。
正如您所看到的Control.Invoke(Action)已经在子中,无论如何检查都是调用是必需的
-我知道检查的目的,但是您正在创建
MethodInvoker
Sub()
lambda,而不是直接使用
Action
参数调用
Control.Invoke(Action)
。:)@VisualEvent由于我从未测试过调用父控件而不是单个子控件,所以我会这样做。谢谢
textbox1.InvokeCustom(sub() textbox1.text = "abc")