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