等待多个应用程序从批处理文件异步运行以完成

时间:2013-09-12 07:50:10

标签: batch-file wait multiple-instances

有一个简单的Windows批处理文件可以运行多个应用程序实例:

start app.exe param1
start app.exe param2

有没有办法同时异步运行它们(上面做了)并等待它们完成执行其他操作 - 比如C#

Task.WhenAll(tasksList.ToArray());
/* Process tasksList.Result */


/ wait开关在这里没有帮助,如果特定实例仍在运行,可能会进行一些轮询。

6 个答案:

答案 0 :(得分:20)

我认为这个问题与Waiting for parallel batch scripts略有不同,因为此应用程序正在等待.exe进程完成而不是批处理脚本。但解决方案几乎相同。

您必须在主批处理脚本中实例化某种形式的轮询。您可以通过重定向有效地创建锁定文件。锁定文件保持锁定状态,直到进程终止。您的批处理脚本轮询,检查它是否可以打开所有锁定文件。一旦成功,就知道所有过程都已结束。

以下解决方案的唯一显着差异是START直接启动.exe而不是通过CMD /C启动批处理。我还了解到(call )是一种非常快速的方法,可以有效地执行始终成功的无操作。所以我用(call )代替rem

@echo off
setlocal
set "lock=%temp%\wait%random%.lock"

:: Launch processes asynchronously, with stream 9 redirected to a lock file.
:: The lock file will remain locked until the script ends.
start "" 9>"%lock%1" notepad.exe
start "" 9>"%lock%2" notepad.exe

:Wait for both processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%N in (1 2) do (
  (call ) 9>"%lock%%%N" || goto :Wait
) 2>nul

::delete the lock files
del "%lock%*"

:: Finish up
echo Done - ready to continue processing

请参阅Parallel execution of shell processes,了解一种非常复杂的锁定技术应用,该技术可以调节最大并行进程数,并能够通过PSEXEC将进程定向到特定的CPU或计算机。该答案还提供了有关锁文件技术如何工作的更全面的解释。


修改

可以修改等待循环,以便在添加更多进程时不需要更改:

:Wait for all processes to finish (wait until lock files are no longer locked)
1>nul 2>nul ping /n 2 ::1
for %%F in ("%lock%*") do (
  (call ) 9>"%%F" || goto :Wait
) 2>nul

答案 1 :(得分:1)

根据@dbenham回答,这里是我如何让它在for内工作以及无限数量的流程:

setlocal enabledelayedexpansion
for %%a in (*.*) do start "" 9>"%temp%/wait!random!.lock" /b /low "myprogram.exe" -program_parameters

:wait
ping /n 2 ::1 > nul
echo waiting processes to finish...
2>nul del "%temp%\wait*.lock" > nul
if exist "%temp%\wait*.lock" goto :wait

... more commands ...

%random%无法正常工作,因此在调用for时会将其展开,因此会使所有数字都相同。所以我enabledelayedexpansion并使用!random!

在循环中我尝试删除所有文件。 2>nul将确保在屏幕上显示任何错误。只有当所有内容都可以删除时才会通过(if exist)。

答案 2 :(得分:0)

基本上,你正在使用START命令正确地执行它,因为它适合你现在需要的东西。

此外,我建议您参考这个好的答案:https://stackoverflow.com/a/1449192/952310

<强>更新

要等待每个程序完成,请使用/ W开关,查看:

start /w app.exe param1
start /w app.exe param2

答案 3 :(得分:0)

您正在启动同一app.exe的多个实例?

  • 全部启动
  • 循环tasklist |find "app.exe",直到%errorlevel%1
  • 继续使用您的脚本

答案 4 :(得分:0)

Powershell有更复杂的方法可以在没有等待循环的情况下完成它。您可以使用PowerShell包装或调用脚本,甚至可以实现您首选的托管解决方案,就像在C#中一样。

答案 5 :(得分:0)

在单独的批处理文件asynchBatch.bat中:

start app.exe param1
start app.exe param2

然后在调用者批处理文件中写:

call asynchBatch.bat
other executions
...

只有在app.exe param1和app.exe param2完成后才会启动其他执行。