Make long running tasks cancellable
This commit is contained in:
parent
b6fba7eb7c
commit
9ffe5c200d
3 changed files with 26 additions and 9 deletions
|
@ -11,10 +11,10 @@ using System.Threading.Tasks;
|
|||
|
||||
public abstract class Archive : IDisposable
|
||||
{
|
||||
public static async Task<Archive> Create(string path)
|
||||
public static async Task<Archive> Create(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (path.EndsWith(".tar.gz"))
|
||||
return await TarArchive.Create(path);
|
||||
return await TarArchive.Create(path, cancellationToken);
|
||||
else if (path.EndsWith(".zip"))
|
||||
return ZipFileArchive.Create(path);
|
||||
else
|
||||
|
@ -40,7 +40,7 @@ public abstract class Archive : IDisposable
|
|||
_extractedFolder = extractedFolder;
|
||||
}
|
||||
|
||||
public static async Task<TarArchive> Create(string path, CancellationToken cancellationToken = default)
|
||||
public static new async Task<TarArchive> Create(string path, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var tmpFolder = Directory.CreateTempSubdirectory(nameof(FindArchiveDiffs));
|
||||
using (var gzStream = File.OpenRead (path))
|
||||
|
@ -90,7 +90,7 @@ public abstract class Archive : IDisposable
|
|||
_archive = archive;
|
||||
}
|
||||
|
||||
public static new ZipFileArchive Create(string path)
|
||||
public static ZipFileArchive Create(string path)
|
||||
{
|
||||
return new ZipFileArchive(new ZipArchive(File.OpenRead(path)));
|
||||
}
|
||||
|
|
|
@ -5,12 +5,13 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
public class FindArchiveDiffs : Microsoft.Build.Utilities.Task
|
||||
public class FindArchiveDiffs : Microsoft.Build.Utilities.Task, ICancelableTask
|
||||
{
|
||||
public class ArchiveItem
|
||||
{
|
||||
|
@ -26,6 +27,13 @@ public class FindArchiveDiffs : Microsoft.Build.Utilities.Task
|
|||
[Output]
|
||||
public ITaskItem[] ContentDifferences { get; set; } = [];
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource = new();
|
||||
private CancellationToken cancellationToken => _cancellationTokenSource.Token;
|
||||
public void Cancel()
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
public override bool Execute()
|
||||
{
|
||||
return Task.Run(ExecuteAsync).Result;
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Build.Framework;
|
||||
|
||||
public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task
|
||||
public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task, ICancelableTask
|
||||
{
|
||||
[Required]
|
||||
public required string BuiltSdkPath { get; init; }
|
||||
|
@ -20,8 +21,16 @@ public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task
|
|||
return Task.Run(ExecuteAsync).Result;
|
||||
}
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource = new();
|
||||
private CancellationToken cancellationToken => _cancellationTokenSource.Token;
|
||||
public void Cancel()
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
}
|
||||
|
||||
public async Task<bool> ExecuteAsync()
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var (versionString, rid, extension) = Archive.GetInfoFromArchivePath(BuiltSdkPath);
|
||||
|
||||
string downloadUrl = GetLatestOfficialSdkUrl(versionString, rid, extension);
|
||||
|
@ -32,14 +41,14 @@ public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task
|
|||
AllowAutoRedirect = false
|
||||
};
|
||||
var client = new HttpClient(handler);
|
||||
var redirectResponse = await client.GetAsync(downloadUrl);
|
||||
var redirectResponse = await client.GetAsync(downloadUrl, cancellationToken);
|
||||
// aka.ms returns a 301 for valid redirects and a 302 to Bing for invalid URLs
|
||||
if (redirectResponse.StatusCode != HttpStatusCode.Moved)
|
||||
{
|
||||
Log.LogMessage(MessageImportance.High, $"Failed to download '{downloadUrl}': invalid aka.ms URL");
|
||||
return true;
|
||||
}
|
||||
var packageResponse = await client.GetAsync(redirectResponse.Headers.Location!);
|
||||
var packageResponse = await client.GetAsync(redirectResponse.Headers.Location!, cancellationToken);
|
||||
|
||||
var packageUriPath = packageResponse.RequestMessage!.RequestUri!.LocalPath;
|
||||
string downloadedVersion = PathWithVersions.GetVersionInPath(packageUriPath).ToString();
|
||||
|
@ -48,7 +57,7 @@ public class GetClosestOfficialSdk : Microsoft.Build.Utilities.Task
|
|||
Log.LogMessage($"Copying {packageUriPath} to {ClosestOfficialSdkPath}");
|
||||
using (var file = File.Create(ClosestOfficialSdkPath))
|
||||
{
|
||||
await packageResponse.Content.CopyToAsync(file);
|
||||
await packageResponse.Content.CopyToAsync(file, cancellationToken);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue