【问题标题】:MSBuild - wait for x secondsMSBuild - 等待 x 秒
【发布时间】:2016-12-16 16:27:54
【问题描述】:

我有一个部署 Web 应用程序的 MSBuild 脚本。 它通过将“app_offline.htm”文件复制到服务器来停止当前的 Web 应用程序。 在此之后,它会删除其他文件,然后将新文件复制到服务器。

我需要在复制“app_offline.htm”和删除之间添加延迟。

我当前的脚本会抛出错误,因为当脚本尝试删除文件时文件仍处于锁定状态。

在 MSBuild 中执行此操作的最佳方法是什么?

我的停止任务如下所示...

  <Target Name="Stop">
    <WriteLinesToFile File="$(DeployDirectory)\app_offline.htm" Lines="Offline for maintenance" Overwrite="true" Encoding="Unicode"/>
  </Target>

我的删除任务如下所示...

  <Target Name="Clean">
    <ItemGroup>
      <Files Include="$(DeployDirectory)\**\*" Exclude="$(DeployDirectory)\app_offline.htm" />
      <Files Include="$(LogDirectory)\*" />
    </ItemGroup>
    <Delete Files="@(Files)" />
  </Target>

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    有多种选择:

    1. MSBuild Community Tasks 有内置的Sleep 任务。你可以这样使用它:

      <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" />
      <Sleep Milliseconds="300" />
      
    2. MSBuild Extension Pack 还包含提供睡眠功能的内置Thread 任务。使用示例is here

    3. 当然,任何与 cmd 兼容的等待都可以通过 Exec 命令工作:

      • 已经提到&lt;Exec Command="ping -n 6 127.0.0.1 &gt; nul" /&gt;
      • &lt;Exec Command="sleep 5" /&gt; 也很适合我。
    4. 您可以为此目的定义 MSBuild 内联 C# 任务:

      <UsingTask TaskName="Sleep" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
        <ParameterGroup>
          <!-- Delay in milliseconds -->
          <Delay ParameterType="System.Int32" Required="true" />
        </ParameterGroup>
        <Task>
          <Code Type="Fragment" Language="cs">
            <![CDATA[
      System.Threading.Thread.Sleep(this.Delay);
      ]]>
          </Code>
        </Task>
      </UsingTask>
      
      ...
      
      <Sleep Delay="5000"/>
      

    【讨论】:

    • 我在发现一个 ping -n 16 127.0.0.1 莫名其妙地添加到我们的一个构建脚本中后来到这里,并且想知道为什么我们要 ping localhost。请,如果您打算使用ping 睡觉,请至少添加一个代码注释来解释原因。
    【解决方案2】:

    您可以使用 Exec 任务调用来自How to sleep for 5 seconds in Windows's Command Prompt? (or DOS) 的解决方案之一,例如ping 是非迭代的,所以应该可以工作。类似的东西

    <Exec Command="ping -n 6 127.0.0.1 > nul"/>
    <Delete Files="@(Files)" />
    

    另见https://github.com/Microsoft/msbuild/issues/199:将来删除任务可能会获得与复制任务现在类似的参数。因此,另一种选择是使用设置了重试计数的复制来尝试覆盖正在使用的文件之一,当成功时,您知道它不再被使用并且可以继续删除:

    <Copy SourceFiles="someFile" DestinationFile="$(DeployDirectory)\someFileInUse" 
          RetryDelayMilliseconds="1000" Retries="5"/>
    <Delete Files="@(Files)" />
    

    当然,如果超时到期并且文件仍在使用中,这两种解决方案都会失败,但是在不冒无限等待风险的情况下,没有办法解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-13
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2017-09-02
      • 2014-10-09
      相关资源
      最近更新 更多