Skip to content

Instantly share code, notes, and snippets.

@StephenCleary
Created March 3, 2015 01:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StephenCleary/82813efb37c40a79523d to your computer and use it in GitHub Desktop.
Save StephenCleary/82813efb37c40a79523d to your computer and use it in GitHub Desktop.
How Task.Run responds to CancellationToken
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class TaskRunCancellationTokenUnitTests
{
[TestMethod]
public void CancellationTokenPassedToSynchronousTaskRun_CancelsTaskWithTaskCanceledException()
{
var cts = new CancellationTokenSource();
cts.Cancel();
var task = Task.Run(() => { }, cts.Token);
TaskCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
// TaskCanceledException derives from OperationCanceledException
exception = ex.InnerException as TaskCanceledException;
}
Assert.IsTrue(task.IsCanceled);
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
[TestMethod]
public void CancellationTokenPassedToAsynchronousTaskRun_CancelsTaskWithTaskCanceledException()
{
var cts = new CancellationTokenSource();
cts.Cancel();
var task = Task.Run(async () => { await Task.Yield(); }, cts.Token);
TaskCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
// TaskCanceledException derives from OperationCanceledException
exception = ex.InnerException as TaskCanceledException;
}
Assert.IsTrue(task.IsCanceled);
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
[TestMethod]
public void CancellationTokenObservedBySynchronousDelegate_FaultsTaskWithOperationCanceledException()
{
var cts = new CancellationTokenSource();
cts.Cancel();
var task = Task.Run(() => { cts.Token.ThrowIfCancellationRequested(); });
OperationCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
exception = ex.InnerException as OperationCanceledException;
}
Assert.IsTrue(task.IsFaulted);
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
[TestMethod]
public void CancellationTokenObservedByAsynchronousDelegate_CancelsTaskWithTaskCanceledException()
{
var cts = new CancellationTokenSource();
cts.Cancel();
var task = Task.Run(async () =>
{
await Task.Yield();
cts.Token.ThrowIfCancellationRequested();
});
OperationCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
// TaskCanceledException derives from OperationCanceledException
exception = ex.InnerException as TaskCanceledException;
}
Assert.IsTrue(task.IsCanceled); // Note: canceled, not faulted!
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
[TestMethod]
public void CancellationTokenObservedSynchronouslyAndPassed_CancelsTaskWithTaskCanceledException()
{
var cts = new CancellationTokenSource();
var taskReady = new ManualResetEvent(false);
var task = Task.Run(() =>
{
taskReady.Set();
while (true)
cts.Token.ThrowIfCancellationRequested();
}, cts.Token);
taskReady.WaitOne();
cts.Cancel();
OperationCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
// TaskCanceledException derives from OperationCanceledException
exception = ex.InnerException as TaskCanceledException;
}
Assert.IsTrue(task.IsCanceled);
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
[TestMethod]
public void CancellationTokenObservedAsynchronouslyAndPassed_CancelsTaskWithTaskCanceledException()
{
var cts = new CancellationTokenSource();
var taskReady = new ManualResetEvent(false);
var task = Task.Run(async () =>
{
await Task.Yield();
taskReady.Set();
while (true)
cts.Token.ThrowIfCancellationRequested();
}, cts.Token);
taskReady.WaitOne();
cts.Cancel();
OperationCanceledException exception = null;
try
{
task.Wait();
}
catch (AggregateException ex)
{
// TaskCanceledException derives from OperationCanceledException
exception = ex.InnerException as TaskCanceledException;
}
Assert.IsTrue(task.IsCanceled);
Assert.IsNotNull(exception);
Assert.AreEqual(cts.Token, exception.CancellationToken);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment