TaskCompletionSource cleanup

This commit is contained in:
Dominion
2023-04-10 13:44:19 -04:00
parent 1ae77311c1
commit c0da716708
18 changed files with 89 additions and 87 deletions
@@ -276,7 +276,7 @@ namespace Tgstation.Server.Host.Components.Byond
/// <returns>A <see cref="Task"/> representing the running operation.</returns>
async Task<string> InstallVersion(Version version, Stream customVersionStream, CancellationToken cancellationToken)
{
var ourTcs = new TaskCompletionSource<object>();
var ourTcs = new TaskCompletionSource();
Task inProgressTask;
string versionKey;
bool installed;
@@ -370,7 +370,7 @@ namespace Tgstation.Server.Host.Components.Byond
throw;
}
ourTcs.SetResult(null);
ourTcs.SetResult();
}
catch (Exception e)
{
@@ -109,9 +109,9 @@ namespace Tgstation.Server.Host.Components.Chat
Task messageSendTask;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that completes when <see cref="ChatBotSettings"/>s change.
/// The <see cref="TaskCompletionSource"/> that completes when <see cref="ChatBotSettings"/>s change.
/// </summary>
TaskCompletionSource<object> connectionsUpdated;
TaskCompletionSource connectionsUpdated;
/// <summary>
/// Used for remapping <see cref="ChannelRepresentation.RealId"/>s.
@@ -157,7 +157,7 @@ namespace Tgstation.Server.Host.Components.Chat
mappedChannels = new Dictionary<ulong, ChannelMapping>();
trackingContexts = new List<IChatTrackingContext>();
handlerCts = new CancellationTokenSource();
connectionsUpdated = new TaskCompletionSource<object>();
connectionsUpdated = new TaskCompletionSource();
messageSendTask = Task.CompletedTask;
channelIdCounter = 1;
@@ -293,8 +293,8 @@ namespace Tgstation.Server.Host.Components.Chat
{
// same thread shennanigans
var oldOne = connectionsUpdated;
connectionsUpdated = new TaskCompletionSource<object>();
oldOne.SetResult(null);
connectionsUpdated = new TaskCompletionSource();
oldOne.SetResult();
}
var reconnectionUpdateTask = provider?.SetReconnectInterval(
@@ -88,9 +88,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
CancellationTokenSource gatewayCts;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> for the initial gateway connection event.
/// The <see cref="TaskCompletionSource"/> for the initial gateway connection event.
/// </summary>
TaskCompletionSource<object> gatewayReadyTcs;
TaskCompletionSource gatewayReadyTcs;
/// <summary>
/// The <see cref="Task"/> representing the lifetime of the client.
@@ -559,7 +559,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
throw new ArgumentNullException(nameof(readyEvent));
Logger.LogTrace("Gatway ready. Version: {version}", readyEvent.Version);
gatewayReadyTcs?.TrySetResult(null);
gatewayReadyTcs?.TrySetResult();
return Task.FromResult(Result.FromSuccess());
}
@@ -580,7 +580,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
var gatewayClient = serviceProvider.GetRequiredService<DiscordGatewayClient>();
Task<Result> localGatewayTask;
gatewayReadyTcs = new TaskCompletionSource<object>();
gatewayReadyTcs = new TaskCompletionSource();
using var gatewayConnectionAbortRegistration = cancellationToken.Register(() => gatewayReadyTcs.TrySetCanceled());
gatewayCancellationToken.Register(() => Logger.LogTrace("Stopping gateway client..."));
@@ -380,7 +380,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
Logger.LogTrace("Processing initial messages...");
await NonBlockingListen(cancellationToken);
var nickCheckCompleteTcs = new TaskCompletionSource<object>();
var nickCheckCompleteTcs = new TaskCompletionSource();
using (cancellationToken.Register(() => nickCheckCompleteTcs.TrySetCanceled()))
{
listenTask = Task.Factory.StartNew(
@@ -399,7 +399,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
client.RfcNick(nickname);
}
nickCheckCompleteTcs.TrySetResult(null);
nickCheckCompleteTcs.TrySetResult();
Logger.LogTrace("Starting blocking listen...");
try
@@ -40,9 +40,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
readonly Queue<Message> messageQueue;
/// <summary>
/// The backing <see cref="TaskCompletionSource{TResult}"/> for <see cref="InitialConnectionJob"/>.
/// The backing <see cref="TaskCompletionSource"/> for <see cref="InitialConnectionJob"/>.
/// </summary>
readonly TaskCompletionSource<object> initialConnectionTcs;
readonly TaskCompletionSource initialConnectionTcs;
/// <summary>
/// Used for synchronizing access to <see cref="reconnectCts"/> and <see cref="reconnectTask"/>.
@@ -50,9 +50,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
readonly object reconnectTaskLock;
/// <summary>
/// <see cref="TaskCompletionSource{TResult}"/> that completes while <see cref="messageQueue"/> isn't empty.
/// <see cref="TaskCompletionSource"/> that completes while <see cref="messageQueue"/> isn't empty.
/// </summary>
TaskCompletionSource<object> nextMessage;
TaskCompletionSource nextMessage;
/// <summary>
/// The auto reconnect <see cref="Task"/>.
@@ -77,8 +77,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
ChatBot = chatBot ?? throw new ArgumentNullException(nameof(chatBot));
messageQueue = new Queue<Message>();
nextMessage = new TaskCompletionSource<object>();
initialConnectionTcs = new TaskCompletionSource<object>();
nextMessage = new TaskCompletionSource();
initialConnectionTcs = new TaskCompletionSource();
reconnectTaskLock = new object();
logger.LogTrace("Created.");
@@ -115,7 +115,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
/// <inheritdoc />
public void InitialMappingComplete() => initialConnectionTcs.TrySetResult(null);
public void InitialMappingComplete() => initialConnectionTcs.TrySetResult();
/// <inheritdoc />
public async Task<IReadOnlyCollection<Tuple<ChatChannel, ChannelRepresentation>>> MapChannels(IEnumerable<ChatChannel> channels, CancellationToken cancellationToken)
@@ -126,7 +126,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
catch
{
initialConnectionTcs.TrySetResult(null);
initialConnectionTcs.TrySetResult();
throw;
}
}
@@ -142,7 +142,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
{
var result = messageQueue.Dequeue();
if (messageQueue.Count == 0)
nextMessage = new TaskCompletionSource<object>();
nextMessage = new TaskCompletionSource();
return result;
}
}
@@ -215,7 +215,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
lock (messageQueue)
{
messageQueue.Enqueue(message);
nextMessage.TrySetResult(null);
nextMessage.TrySetResult();
}
}
@@ -290,7 +290,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers
}
catch
{
initialConnectionTcs.TrySetResult(null);
initialConnectionTcs.TrySetResult();
throw;
}
},
@@ -80,9 +80,9 @@ namespace Tgstation.Server.Host.Components.Deployment
Task cleanupTask;
/// <summary>
/// <see cref="TaskCompletionSource{TResult}"/> resulting in the latest <see cref="DmbProvider"/> yet to exist.
/// <see cref="TaskCompletionSource"/> resulting in the latest <see cref="DmbProvider"/> yet to exist.
/// </summary>
TaskCompletionSource<object> newerDmbTcs;
TaskCompletionSource newerDmbTcs;
/// <summary>
/// The latest <see cref="DmbProvider"/>.
@@ -119,7 +119,7 @@ namespace Tgstation.Server.Host.Components.Deployment
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
cleanupTask = Task.CompletedTask;
newerDmbTcs = new TaskCompletionSource<object>();
newerDmbTcs = new TaskCompletionSource();
cleanupCts = new CancellationTokenSource();
jobLockCounts = new Dictionary<long, int>();
}
@@ -156,8 +156,8 @@ namespace Tgstation.Server.Host.Components.Deployment
// Oh god dammit
var temp = newerDmbTcs;
newerDmbTcs = new TaskCompletionSource<object>();
temp.SetResult(nextDmbProvider);
newerDmbTcs = new TaskCompletionSource();
temp.SetResult();
}
}
@@ -35,9 +35,9 @@ namespace Tgstation.Server.Host.Components
readonly object referenceCountLock;
/// <summary>
/// Backing <see cref="TaskCompletionSource{TResult}"/> for <see cref="OnZeroReferences"/>.
/// Backing <see cref="TaskCompletionSource"/> for <see cref="OnZeroReferences"/>.
/// </summary>
TaskCompletionSource<object> onZeroReferencesTcs;
TaskCompletionSource onZeroReferencesTcs;
/// <summary>
/// Count of active <see cref="IInstanceReference"/>s.
@@ -64,7 +64,7 @@ namespace Tgstation.Server.Host.Components
lock (referenceCountLock)
{
if (referenceCount++ == 0)
onZeroReferencesTcs = new TaskCompletionSource<object>();
onZeroReferencesTcs = new TaskCompletionSource();
try
{
@@ -72,7 +72,7 @@ namespace Tgstation.Server.Host.Components
{
lock (referenceCountLock)
if (--referenceCount == 0)
onZeroReferencesTcs.SetResult(null);
onZeroReferencesTcs.SetResult();
});
}
catch
@@ -117,9 +117,9 @@ namespace Tgstation.Server.Host.Components
readonly SwarmConfiguration swarmConfiguration;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> for <see cref="Ready"/>.
/// The <see cref="TaskCompletionSource"/> for <see cref="Ready"/>.
/// </summary>
readonly TaskCompletionSource<object> readyTcs;
readonly TaskCompletionSource readyTcs;
/// <summary>
/// If the <see cref="InstanceManager"/> has been <see cref="DisposeAsync"/>'d.
@@ -173,7 +173,7 @@ namespace Tgstation.Server.Host.Components
instances = new Dictionary<long, InstanceContainer>();
bridgeHandlers = new Dictionary<string, IBridgeHandler>();
readyTcs = new TaskCompletionSource<object>();
readyTcs = new TaskCompletionSource();
instanceStateChangeSemaphore = new SemaphoreSlim(1);
}
@@ -430,7 +430,7 @@ namespace Tgstation.Server.Host.Components
jobManager.Activate();
logger.LogInformation("Server ready!");
readyTcs.SetResult(null);
readyTcs.SetResult();
}
catch (OperationCanceledException ex)
{
@@ -76,9 +76,9 @@ namespace Tgstation.Server.Host.Components.Session
public ReattachInformation ReattachInformation { get; }
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that completes when DD makes it's first bridge request.
/// The <see cref="TaskCompletionSource"/> that completes when DD makes it's first bridge request.
/// </summary>
readonly TaskCompletionSource<object> initialBridgeRequestTcs;
readonly TaskCompletionSource initialBridgeRequestTcs;
/// <summary>
/// The <see cref="Instance"/> metadata.
@@ -141,14 +141,14 @@ namespace Tgstation.Server.Host.Components.Session
ushort? nextPort;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that completes when DD tells us about a reboot.
/// The <see cref="TaskCompletionSource"/> that completes when DD tells us about a reboot.
/// </summary>
TaskCompletionSource<object> rebootTcs;
TaskCompletionSource rebootTcs;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that completes when DD tells us it's primed.
/// The <see cref="TaskCompletionSource"/> that completes when DD tells us it's primed.
/// </summary>
TaskCompletionSource<object> primeTcs;
TaskCompletionSource primeTcs;
/// <summary>
/// If we know DreamDaemon currently has it's port closed.
@@ -219,9 +219,9 @@ namespace Tgstation.Server.Host.Components.Session
apiValidationStatus = ApiValidationStatus.NeverValidated;
released = false;
rebootTcs = new TaskCompletionSource<object>();
primeTcs = new TaskCompletionSource<object>();
initialBridgeRequestTcs = new TaskCompletionSource<object>();
rebootTcs = new TaskCompletionSource();
primeTcs = new TaskCompletionSource();
initialBridgeRequestTcs = new TaskCompletionSource();
reattachTopicCts = new CancellationTokenSource();
synchronizationLock = new object();
@@ -298,7 +298,7 @@ namespace Tgstation.Server.Host.Components.Session
using (LogContext.PushProperty("Instance", metadata.Id))
{
logger.LogTrace("Handling bridge request...");
initialBridgeRequestTcs.TrySetResult(null);
initialBridgeRequestTcs.TrySetResult();
var response = new BridgeResponse();
switch (parameters.CommandType)
@@ -333,8 +333,8 @@ namespace Tgstation.Server.Host.Components.Session
break;
case BridgeCommandType.Prime:
var oldPrimeTcs = primeTcs;
primeTcs = new TaskCompletionSource<object>();
oldPrimeTcs.SetResult(null);
primeTcs = new TaskCompletionSource();
oldPrimeTcs.SetResult();
break;
case BridgeCommandType.Kill:
logger.LogInformation("Bridge requested process termination!");
@@ -425,8 +425,8 @@ namespace Tgstation.Server.Host.Components.Session
}
var oldRebootTcs = rebootTcs;
rebootTcs = new TaskCompletionSource<object>();
oldRebootTcs.SetResult(null);
rebootTcs = new TaskCompletionSource();
oldRebootTcs.SetResult();
break;
case null:
response.ErrorMessage = "Missing commandType!";
@@ -57,9 +57,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
public abstract RebootState? RebootState { get; }
/// <summary>
/// <see cref="TaskCompletionSource{TResult}"/> that completes when <see cref="ActiveLaunchParameters"/> are changed and we are running.
/// <see cref="TaskCompletionSource"/> that completes when <see cref="ActiveLaunchParameters"/> are changed and we are running.
/// </summary>
protected TaskCompletionSource<object> ActiveParametersUpdated { get; set; }
protected TaskCompletionSource ActiveParametersUpdated { get; set; }
/// <summary>
/// The <see cref="ISessionPersistor"/> for the <see cref="WatchdogBase"/>.
@@ -220,7 +220,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
ActiveLaunchParameters = initialLaunchParameters;
releaseServers = false;
ActiveParametersUpdated = new TaskCompletionSource<object>();
ActiveParametersUpdated = new TaskCompletionSource();
restartRegistration = serverControl.RegisterForRestart(this);
try
@@ -261,8 +261,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
if (match || Status == WatchdogStatus.Offline)
return;
ActiveParametersUpdated.TrySetResult(null); // queue an update
ActiveParametersUpdated = new TaskCompletionSource<object>();
ActiveParametersUpdated.TrySetResult(); // queue an update
ActiveParametersUpdated = new TaskCompletionSource();
}
}
@@ -872,7 +872,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
cancellationToken);
// cancel waiting if requested
var cancelTcs = new TaskCompletionSource<object>();
var cancelTcs = new TaskCompletionSource();
var toWaitOn = Task.WhenAny(
activeServerLifetime,
activeServerReboot,
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Globalization;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using Cyberboss.AspNetCore.AsyncInitializer;
using Microsoft.AspNetCore.Authentication.JwtBearer;
@@ -420,9 +419,7 @@ namespace Tgstation.Server.Host.Core
// 503 requests made while the application is starting
applicationBuilder.UseAsyncInitialization(async (cancellationToken) =>
{
var tcs = new TaskCompletionSource<object>();
using (cancellationToken.Register(() => tcs.SetCanceled()))
await Task.WhenAny(tcs.Task, instanceManager.Ready);
await instanceManager.Ready.WithToken(cancellationToken);
});
// suppress OperationCancelledExceptions, they are just aborted HTTP requests
@@ -9,6 +9,11 @@ namespace Tgstation.Server.Host.Extensions
/// </summary>
static class TaskExtensions
{
/// <summary>
/// A <see cref="TaskCompletionSource"/> that never completes.
/// </summary>
private static readonly TaskCompletionSource InfiniteTaskCompletionSource = new TaskCompletionSource();
/// <summary>
/// Create a <see cref="Task"/> that can be awaited while respecting a given <paramref name="cancellationToken"/>.
/// </summary>
@@ -41,7 +46,7 @@ namespace Tgstation.Server.Host.Extensions
if (task == null)
throw new ArgumentNullException(nameof(task));
var cancelTcs = new TaskCompletionSource<object>();
var cancelTcs = new TaskCompletionSource();
using (cancellationToken.Register(() => cancelTcs.SetCanceled()))
await Task.WhenAny(task, cancelTcs.Task);
cancellationToken.ThrowIfCancellationRequested();
@@ -53,6 +58,6 @@ namespace Tgstation.Server.Host.Extensions
/// Creates a <see cref="Task"/> that never completes.
/// </summary>
/// <returns>A never ending <see cref="Task"/>.</returns>
public static Task InfiniteTask() => new TaskCompletionSource<object>().Task;
public static Task InfiniteTask() => InfiniteTaskCompletionSource.Task;
}
}
+4 -4
View File
@@ -44,9 +44,9 @@ namespace Tgstation.Server.Host.Jobs
readonly Dictionary<long, JobHandler> jobs;
/// <summary>
/// <see cref="TaskCompletionSource{TResult}"/> to delay starting jobs until the server is ready.
/// <see cref="TaskCompletionSource"/> to delay starting jobs until the server is ready.
/// </summary>
readonly TaskCompletionSource<object> activationTcs;
readonly TaskCompletionSource activationTcs;
/// <summary>
/// <see langword="lock"/> <see cref="object"/> for various operations.
@@ -76,7 +76,7 @@ namespace Tgstation.Server.Host.Jobs
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
jobs = new Dictionary<long, JobHandler>();
activationTcs = new TaskCompletionSource<object>();
activationTcs = new TaskCompletionSource();
synchronizationLock = new object();
addCancelLock = new object();
}
@@ -268,7 +268,7 @@ namespace Tgstation.Server.Host.Jobs
public void Activate()
{
logger.LogTrace("Activating job manager...");
activationTcs.SetResult(null);
activationTcs.SetResult();
}
/// <summary>
@@ -80,9 +80,9 @@ namespace Tgstation.Server.Host.Setup
readonly GeneralConfiguration generalConfiguration;
/// <summary>
/// A <see cref="TaskCompletionSource{TResult}"/> that will complete when the <see cref="IConfiguration"/> is reloaded.
/// A <see cref="TaskCompletionSource"/> that will complete when the <see cref="IConfiguration"/> is reloaded.
/// </summary>
TaskCompletionSource<object> reloadTcs;
TaskCompletionSource reloadTcs;
/// <summary>
/// Initializes a new instance of the <see cref="SetupWizard"/> class.
@@ -125,7 +125,7 @@ namespace Tgstation.Server.Host.Setup
configuration
.GetReloadToken()
.RegisterChangeCallback(
state => reloadTcs?.TrySetResult(null),
state => reloadTcs?.TrySetResult(),
null);
}
@@ -942,7 +942,7 @@ namespace Tgstation.Server.Host.Setup
var configBytes = Encoding.UTF8.GetBytes(serializedYaml);
reloadTcs = new TaskCompletionSource<object>();
reloadTcs = new TaskCompletionSource();
try
{
@@ -142,9 +142,9 @@ namespace Tgstation.Server.Host.Swarm
readonly bool swarmController;
/// <summary>
/// A <see cref="TaskCompletionSource{TResult}"/> that is used to force a health check.
/// A <see cref="TaskCompletionSource"/> that is used to force a health check.
/// </summary>
TaskCompletionSource<object> forceHealthCheckTcs;
TaskCompletionSource forceHealthCheckTcs;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that is used to proceed with committing an update.
@@ -233,7 +233,7 @@ namespace Tgstation.Server.Host.Swarm
if (SwarmMode)
{
serverHealthCheckCancellationTokenSource = new CancellationTokenSource();
forceHealthCheckTcs = new TaskCompletionSource<object>();
forceHealthCheckTcs = new TaskCompletionSource();
if (swarmController)
registrationIds = new Dictionary<string, Guid>();
@@ -963,8 +963,8 @@ namespace Tgstation.Server.Host.Swarm
bool TriggerHealthCheck()
{
var currentTcs = forceHealthCheckTcs;
forceHealthCheckTcs = new TaskCompletionSource<object>();
return currentTcs.TrySetResult(null);
forceHealthCheckTcs = new TaskCompletionSource();
return currentTcs.TrySetResult();
}
/// <summary>
@@ -29,9 +29,9 @@ namespace Tgstation.Server.Host.Transfer
readonly TaskCompletionSource<Stream> taskCompletionSource;
/// <summary>
/// The <see cref="TaskCompletionSource{TResult}"/> that completes in <see cref="IDisposable.Dispose"/> or when <see cref="SetErrorMessage(ErrorMessageResponse)"/> is called.
/// The <see cref="TaskCompletionSource"/> that completes in <see cref="IDisposable.Dispose"/> or when <see cref="SetErrorMessage(ErrorMessageResponse)"/> is called.
/// </summary>
readonly TaskCompletionSource<object> completionTcs;
readonly TaskCompletionSource completionTcs;
/// <summary>
/// If synchronous IO is required. Uses a <see cref="FileBufferingReadStream"/> as a backend if set.
@@ -54,7 +54,7 @@ namespace Tgstation.Server.Host.Transfer
ticketExpiryCts = new CancellationTokenSource();
taskCompletionSource = new TaskCompletionSource<Stream>();
completionTcs = new TaskCompletionSource<object>();
completionTcs = new TaskCompletionSource();
this.requireSynchronousIO = requireSynchronousIO;
}
@@ -62,7 +62,7 @@ namespace Tgstation.Server.Host.Transfer
public void Dispose()
{
ticketExpiryCts.Dispose();
completionTcs.TrySetResult(null);
completionTcs.TrySetResult();
}
/// <inheritdoc />
@@ -125,7 +125,7 @@ namespace Tgstation.Server.Host.Transfer
throw new InvalidOperationException("ErrorMessage already set!");
this.errorMessage = errorMessage;
completionTcs.TrySetResult(null);
completionTcs.TrySetResult();
}
}
}
@@ -18,10 +18,10 @@ namespace Tgstation.Server.Host.Tests.Signals
{
var mockServerControl = new Mock<IServerControl>();
var tcs = new TaskCompletionSource<object>();
var tcs = new TaskCompletionSource();
mockServerControl
.Setup(x => x.GracefulShutdown())
.Callback(() => tcs.SetResult(null))
.Callback(() => tcs.SetResult())
.Returns(Task.CompletedTask);
var mockAsyncDelayer = new Mock<IAsyncDelayer>();
@@ -35,14 +35,14 @@ namespace Tgstation.Server.Host.Jobs.Tests
//test with a cancelled cts
using (var cts = new CancellationTokenSource())
{
var tcs = new TaskCompletionSource<object>();
var tcs = new TaskCompletionSource();
currentWaitTask = tcs.Task;
cts.Cancel();
using var handler = new JobHandler(TestJob);
await Assert.ThrowsExceptionAsync<InvalidOperationException>(() => handler.Wait(cts.Token));
handler.Start();
await Assert.ThrowsExceptionAsync<OperationCanceledException>(() => handler.Wait(cts.Token));
tcs.SetResult(null);
tcs.SetResult();
await handler.Wait(default);
}
Assert.IsFalse(cancelled);
@@ -65,14 +65,14 @@ namespace Tgstation.Server.Host.Jobs.Tests
[TestMethod]
public async Task TestCancellation()
{
var tcs = new TaskCompletionSource<object>();
var tcs = new TaskCompletionSource();
currentWaitTask = tcs.Task;
cancelled = false;
using (var handler = new JobHandler(TestJob))
{
handler.Start();
handler.Cancel();
tcs.SetResult(null);
tcs.SetResult();
await handler.Wait(default);
}
Assert.IsTrue(cancelled);