| File: src\SingleError.cs | Web Access |
| Project: Microsoft.DotNet.Arcade.Sdk.csproj (Microsoft.DotNet.Arcade.Sdk) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace Microsoft.DotNet.Arcade.Sdk; // Not opted into multithreading: GetRegisteredTaskObject followed by RegisterTaskObject is not // atomic, so two instances with the same Text running concurrently in one node can both miss the // sentinel and both log the error, defeating the single-error contract. Opting in requires an // atomic register-if-absent primitive, which the BuildEngine task-object API does not offer. public sealed class SingleError : Task { private static readonly string s_cacheKeyPrefix = "SingleError-F88E25C6-1488-4E81-A458-A0921794E6E3:"; [Required] public string Text { get; set; } public override bool Execute() { var key = s_cacheKeyPrefix + Text; var errorReportedSentinel = BuildEngine4.GetRegisteredTaskObject(key, RegisteredTaskObjectLifetime.Build); if (errorReportedSentinel != null) { Log.LogMessage(MessageImportance.Low, Text); return false; } BuildEngine4.RegisterTaskObject(key, new object(), RegisteredTaskObjectLifetime.Build, allowEarlyCollection: true); Log.LogError(Text); return false; } }