MSBuild - 如何创建 "critical section"

标签 msbuild mutex

我有多个项目的并行构建,每个项目在某个时间点都会调用 <Exec />任务。此 exec 任务正在运行 3pty 工具,如果此工具的另一个实例正在运行,该工具会崩溃。有没有一些本地方法如何在 msbuild 中实现“mutex”?

明显的解决方案(有效)是使构建同步 - 但这会减慢整个构建速度。

最佳答案

最后我编写了自己的 msbuild 扩展库,如下所示

msbuild部分:

<UsingTask TaskName="MutexExec" AssemblyFile="$(CommonTasksAssembly)" />

C#部分:

// <PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.9.0" />
// <PackageReference Include="Microsoft.Build.Tasks.Core" Version="16.9.0" />
// <PackageReference Include="Microsoft.Build.Framework" Version="16.9.0" />

using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Tasks;

/// <summary>
/// Like a Exec task, but with critical section
/// </summary>
public class MutexExec : Exec
{
    /// <summary>
    ///     Gets or sets mutex name
    /// </summary>
    [Required]
    public string MutexName { get; set; }

    /// <inheritdoc />
    public override bool Execute()
    {
        var timeout = TimeSpan.FromMinutes(5);
        var stopwatch = Stopwatch.StartNew();
        while (stopwatch.Elapsed < timeout)
        {
            bool createdNew;
            using (var mutex = new Mutex(true, this.MutexName, out createdNew))
            {
                if (createdNew)
                {
                    bool result = base.Execute();
                    try
                    {
                        this.Log.LogMessage(MessageImportance.Normal, "Releasing {0}", this.MutexName);
                        mutex.ReleaseMutex();
                    }
                    catch (Exception e)
                    {
                        this.Log.LogError("Failure releasing {0} - {1}", this.MutexName, e);
                    }

                    return result;
                }
            }

            this.Log.LogMessage(MessageImportance.Normal, "Waiting for {0} - ellapsed {1}", this.MutexName, stopwatch.Elapsed);
            Thread.Sleep(5000);
            continue;
        }

        this.Log.LogError("Failed to acquire {0} in {1}.", this.MutexName, timeout);
        return false;
    }
}

关于MSBuild - 如何创建 "critical section",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62821122/

相关文章:

delphi - 使用 msbuild 构建时从 dproj 中排除搜索路径

command-line - 如何在解决方案名称 (*.sln) 上使用通配符调用 msbuild?

c# - 不存在转换值时 web.config 转换失败

c++ - scoped_lock 的范围

linux - linux' "mutex lock"是使用 "memory barrier"实现的吗?

c - C中的互斥体和线程

msbuild - 展开包含其他属性名称的 MSBuild 属性

c# - Nuget [exec] 警告 : Unable to extract metadata from *. dll

c# - 如何实现 MVC 4 web App 服务器端互斥体

c# - 互斥体不再工作