首页 > 解决方案 > 如果在 VB.NET 中创建了文件,则继续 for 循环

问题描述

我正在使用 COM 接口从第三方程序中导出动画。我正在使用 shell 命令从我的工具中发送带有脚本的导出 COM 命令。

将动画导出命令发送到第三方工具时出现问题。它开始导出,但我的工具正在发送第二个动画导出命令,而最后一个尚未完成。我该如何预防这种情况?

for创建文件后,我想从循环中发送我的 shell 命令。

我的代码如下所示。

Private Sub tlbCheckSolveEvaCtrl_exportmodeshape_Click(sender As Object, e As EventArgs) Handles tlbCheckSolveEvaCtrl_exportmodeshape.Click
    Try
        Dim strArgument As String

        Dim strfilePathEV As String
        Dim strfilePathANI As String
        Dim strfilePathPIC As String

        strfilePathEV = strProjMdlDir & My.Settings.txtCheckSolverOuputDir & strProjMdlName & ".ev.sbr"
        strfilePathANI = strProjMdlDir & "\" & My.Settings.txtProjDirDOC & "\" & My.Settings.txtProjDirANI & "\"
        strfilePathPIC = strProjMdlDir & "\" & My.Settings.txtProjDirDOC & "\" & My.Settings.txtProjDirPIC & "\"

        For i As Integer = 0 To dgvCheckSolveEva.RowCount - 1
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i
            Shell(My.Settings.txtSpckDir & "simpack-post.exe -s qs_mode_shape.qs " & strArgument)
        Next


    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

如果创建了动画文件,我想继续我的for循环strfilePathANI & strProjMdlName & "_" & i & ".mpg",所以我可以开始导出下一个。

标签: vb.netshell

解决方案


最好的方法是使用 .NETProcess并调用该WaitForExit()方法以等待simpack-post.exe其自行关闭。

Shell()是 VB6 时代的一个过时函数,其存在纯粹是为了与该语言部分向后兼容。它不应该在新代码中使用。

基本示例:

Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()

当然,这样做的问题是它可能会阻塞 UI 线程并因此导致它冻结,具体取决于进程退出所需的时间。因此我们应该把它包装在一个Task

Dim c As Integer = dgvCheckSolveEva.RowCount - 1

Task.Run( _
    Sub()
        For i As Integer = 0 To c
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i

            Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
            Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
        Next
    End Sub _
)

请注意,您不能从任务中直接访问 UI。如果你想这样做,你需要Invoke


编辑:

如果您的目标是 .NET Framework 3.5 或更低版本,或者使用 VS 2008 或更低版本,则任务不可用,我们不得不求助于使用常规线程和/或常规方法而不是 Lamba 表达式。

但请注意,同样的规则也适用 - 如果不调用,您将无法访问 UI。

.NET 3.5(或更低版本)使用 VS 2010(及更高版本):

Dim c As Integer = dgvCheckSolveEva.RowCount - 1

Dim t As New Thread( _
    Sub()
        For i As Integer = 0 To c
            strArgument = strfilePathEV & " " & _
                strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
                i

            Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
            Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
        Next
    End Sub _
)
t.IsBackground = True
t.Start()

.NET 3.5(或更低)使用 VS 2008(或更低):

Private Sub tlbCheckSolveEvaCtrl_exportmodeshape_Click(sender As Object, e As EventArgs) Handles tlbCheckSolveEvaCtrl_exportmodeshape.Click

    ...your code...

    Dim c As Integer = dgvCheckSolveEva.RowCount - 1
    Dim t As New Thread(New ParameterizedThreadStart(AddressOf ExportAnimationsThread))
    t.IsBackground = True
    t.Start(c)

    ...your code...
End Sub

Private Sub ExportAnimationsThread(ByVal Count As Integer)
    For i As Integer = 0 To Count
        strArgument = strfilePathEV & " " & _
            strfilePathANI & strProjMdlName & "_" & i & ".mpg" & " " & _
            i

        Dim filePath As String = Path.Combine(My.Settings.txtSpckDir, "simpack-post.exe")
        Process.Start(filePath, "-s qs_mode_shape.qs " & strArgument).WaitForExit()
    Next
End Sub

推荐阅读