我正在使用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"
循环,以便可以开始导出下一个动画文件。
答案 0 :(得分:5)
最好的方法是使用.NET Process
class并调用WaitForExit()
method,以等待simpack-post.exe
关闭。
Shell()
是VB6-era的过时功能,其存在纯粹是为了与该语言部分向后兼容。不应在新代码中使用它。
基本示例:
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。
使用VS 2010(及更高版本)的.NET 3.5(或更低版本):
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()
使用VS 2008(或更低版本)的.NET 3.5(或更低版本):
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