Add build cancellation

This commit is contained in:
Matt Parker
2025-08-03 00:27:33 +10:00
parent 22f11a5587
commit 9a3fe17b88
3 changed files with 12 additions and 4 deletions

View File

@@ -8,13 +8,15 @@ public static class BuildManagerExtensions
/// Convenience method. Submits a lone build request and returns a Task that will complete when results are available. /// Convenience method. Submits a lone build request and returns a Task that will complete when results are available.
/// </summary> /// </summary>
/// <exception cref="InvalidOperationException">Thrown if a build is already in progress.</exception> /// <exception cref="InvalidOperationException">Thrown if a build is already in progress.</exception>
public static async Task<BuildResult> BuildAsync(this BuildManager buildManager, BuildParameters parameters, BuildRequestData requestData) public static async Task<BuildResult> BuildAsync(this BuildManager buildManager, BuildParameters parameters, BuildRequestData requestData, CancellationToken cancellationToken = default)
{ {
BuildResult result; BuildResult result;
buildManager.BeginBuild(parameters); buildManager.BeginBuild(parameters);
try try
{ {
var tcs = new TaskCompletionSource<BuildResult>(TaskCreationOptions.RunContinuationsAsynchronously); var tcs = new TaskCompletionSource<BuildResult>(TaskCreationOptions.RunContinuationsAsynchronously);
await using var cancellationTokenRegistration = cancellationToken.Register(() => buildManager.CancelAllSubmissions());
cancellationTokenRegistration.ConfigureAwait(false);
try try
{ {

View File

@@ -18,7 +18,7 @@ public class BuildService
{ {
public event Func<Task> BuildStarted = () => Task.CompletedTask; public event Func<Task> BuildStarted = () => Task.CompletedTask;
public ChannelTextWriter BuildTextWriter { get; } = new ChannelTextWriter(); public ChannelTextWriter BuildTextWriter { get; } = new ChannelTextWriter();
public async Task MsBuildSolutionAsync(string solutionFilePath, BuildType buildType = BuildType.Build) public async Task MsBuildSolutionAsync(string solutionFilePath, BuildType buildType = BuildType.Build, CancellationToken cancellationToken = default)
{ {
var normalOut = Console.Out; var normalOut = Console.Out;
Console.SetOut(BuildTextWriter); Console.SetOut(BuildTextWriter);
@@ -50,7 +50,7 @@ public class BuildService
await BuildStarted.Invoke().ConfigureAwait(false); await BuildStarted.Invoke().ConfigureAwait(false);
var timer = Stopwatch.StartNew(); var timer = Stopwatch.StartNew();
var buildResult = await BuildManager.DefaultBuildManager.BuildAsync(buildParameters, buildRequest).ConfigureAwait(false); var buildResult = await BuildManager.DefaultBuildManager.BuildAsync(buildParameters, buildRequest, cancellationToken).ConfigureAwait(false);
timer.Stop(); timer.Stop();
Console.WriteLine($"Build result: {buildResult.OverallResult} in {timer.ElapsedMilliseconds}ms"); Console.WriteLine($"Build result: {buildResult.OverallResult} in {timer.ElapsedMilliseconds}ms");
} }

View File

@@ -17,6 +17,9 @@
<MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Primary" OnClick="@CleanSolution">Clean</MudButton> <MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Primary" OnClick="@CleanSolution">Clean</MudButton>
<MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Primary" OnClick="@RestoreSolution">Restore</MudButton> <MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Primary" OnClick="@RestoreSolution">Restore</MudButton>
</MudButtonGroup> </MudButtonGroup>
<MudButton OnClick="@CancelBuild">
<MudIcon Icon="@Icons.Material.Filled.Cancel" Size="Size.Medium" Color="Color.Default" />
</MudButton>
<MudSpacer /> <MudSpacer />
<MudStack Row="true" AlignItems="AlignItems.Center"> <MudStack Row="true" AlignItems="AlignItems.Center">
<MudButton OnClick="@TerminalDrawerToggle"> <MudButton OnClick="@TerminalDrawerToggle">
@@ -88,6 +91,7 @@
} }
} }
private CancellationTokenSource _cancellationTokenSource = null!;
private async Task BuildSolution() => await MsBuildSolution(BuildType.Build); private async Task BuildSolution() => await MsBuildSolution(BuildType.Build);
private async Task RebuildSolution() => await MsBuildSolution(BuildType.Rebuild); private async Task RebuildSolution() => await MsBuildSolution(BuildType.Rebuild);
private async Task CleanSolution() => await MsBuildSolution(BuildType.Clean); private async Task CleanSolution() => await MsBuildSolution(BuildType.Clean);
@@ -95,8 +99,10 @@
private async Task MsBuildSolution(BuildType buildType) private async Task MsBuildSolution(BuildType buildType)
{ {
if (AppState.IdeSettings.OpenTerminalOnBuildRebuildRestore) _terminalDrawerOpen = true; if (AppState.IdeSettings.OpenTerminalOnBuildRebuildRestore) _terminalDrawerOpen = true;
await BuildService.MsBuildSolutionAsync(_solutionFilePath!, buildType); _cancellationTokenSource = new CancellationTokenSource();
await BuildService.MsBuildSolutionAsync(_solutionFilePath!, buildType, _cancellationTokenSource.Token);
} }
private async Task CancelBuild() => await _cancellationTokenSource.CancelAsync();
private async Task OpenSettingsDialog() private async Task OpenSettingsDialog()
{ {