implement end running project

This commit is contained in:
Matt Parker
2025-08-08 01:26:23 +10:00
parent f89fff7462
commit ea5bb6ac53
4 changed files with 24 additions and 4 deletions

View File

@@ -20,6 +20,9 @@ public class RunService
var semaphoreSlim = _projectLocks.GetOrAdd(project, new SemaphoreSlim(1, 1));
var waitResult = await semaphoreSlim.WaitAsync(0);
if (waitResult is false) throw new InvalidOperationException($"Project {project.Name} is already running.");
if (project.RunningCancellationTokenSource is not null) throw new InvalidOperationException($"Project {project.Name} is already running with a cancellation token source.");
project.RunningCancellationTokenSource = new CancellationTokenSource();
try
{
var processStartInfo = new ProcessStartInfo2
@@ -48,15 +51,31 @@ public class RunService
project.Running = true;
GlobalEvents.InvokeProjectsRunningChanged();
await process.WaitForExitAsync();
await process.WaitForExitAsync().WaitAsync(project.RunningCancellationTokenSource.Token).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
if (project.RunningCancellationTokenSource.IsCancellationRequested)
{
process.End();
await process.WaitForExitAsync();
}
project.Running = false;
GlobalEvents.InvokeProjectsRunningChanged();
Console.WriteLine("Project ran successfully.");
Console.WriteLine("Project finished running");
}
finally
{
semaphoreSlim.Release();
}
}
public async Task CancelRunningProject(SharpIdeProjectModel project)
{
Guard.Against.Null(project, nameof(project));
if (project.Running is false) throw new InvalidOperationException($"Project {project.Name} is not running.");
if (project.RunningCancellationTokenSource is null) throw new InvalidOperationException($"Project {project.Name} does not have a running cancellation token source.");
await project.RunningCancellationTokenSource.CancelAsync();
project.RunningCancellationTokenSource.Dispose();
project.RunningCancellationTokenSource = null;
}
}

View File

@@ -28,6 +28,7 @@ public class SharpIdeProjectModel : ISharpIdeNode
public required List<SharpIdeFile> Files { get; set; }
public bool Expanded { get; set; }
public bool Running { get; set; }
public CancellationTokenSource? RunningCancellationTokenSource { get; set; }
public required Task<Project> MsBuildEvaluationProjectTask { get; set; }
public Project MsBuildEvaluationProject => MsBuildEvaluationProjectTask.IsCompletedSuccessfully

View File

@@ -9,7 +9,7 @@
<ItemGroup>
<!-- If any Microsoft.Build.dll ends up in the output, it will be prioritised for loading by MSBuild Nodes -->
<PackageReference Include="Ardalis.GuardClauses" Version="5.0.0" />
<PackageReference Include="AsyncReadProcess" Version="1.0.0-preview5" />
<PackageReference Include="AsyncReadProcess" Version="1.0.0-preview6" />
<PackageReference Include="Microsoft.Build" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Framework" Version="17.14.8" ExcludeAssets="runtime" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.9.1" />

View File

@@ -23,7 +23,7 @@
<MudSpacer/>
@if (project.Running)
{
<MudButton Style="min-width: 20px;">
<MudButton Style="min-width: 20px;" OnClick="@(async () => await RunService.CancelRunningProject(project))">
<MudIcon Icon="@Icons.Material.Filled.Stop" Size="Size.Medium" Color="Color.Error"/>
</MudButton>
}