| File: Annotations\MauiBuildQueueAnnotation.cs | Web Access |
| Project: src\src\Aspire.Hosting.Maui\Aspire.Hosting.Maui.csproj (Aspire.Hosting.Maui) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Concurrent; using Aspire.Hosting.ApplicationModel; namespace Aspire.Hosting.Maui.Annotations; /// <summary> /// Annotation added to <see cref="MauiProjectResource"/> to serialize builds across /// platform resources that share the same project. /// </summary> internal sealed class MauiBuildQueueAnnotation : IResourceAnnotation { /// <summary> /// Gets the semaphore used to serialize builds for this project. /// </summary> public SemaphoreSlim BuildSemaphore { get; } = new(1, 1); /// <summary> /// Per-resource CTS that allows the stop command to cancel a queued or building resource. /// The key is the resource name. /// </summary> public ConcurrentDictionary<string, CancellationTokenSource> ResourceCancellations { get; } = new(); /// <summary> /// Cancels a resource's queued or building state. /// </summary> /// <returns><c>true</c> if the resource was found and cancelled; <c>false</c> otherwise.</returns> public bool CancelResource(string resourceName) { if (ResourceCancellations.TryRemove(resourceName, out var cts)) { try { cts.Cancel(throwOnFirstException: false); } catch (ObjectDisposedException) { // The CTS was disposed by the event handler's using block after the build // completed naturally at the exact moment the user clicked stop. return false; } catch (AggregateException) { // Cancel(throwOnFirstException: false) still invokes all callbacks before // surfacing their failures. The resource was found and cancellation was // requested, so don't let a callback failure escape the stop command path. } return true; } return false; } }