任何人都可以帮助并确定这是我的错误还是不太可能的.Net错误?
下面的代码显示了一个Main()例程,它启动了10个任务,使用DoNothing()方法作为基础方法,SemphoreSlim允许同时运行3个任务。 然后Main()等待一段时间:
Thread.Sleep(3000);
等待之后我们取消所有任务:
cancel.Cancel();
此时我预计.ContinueWith(..)将接管:
doNothingTasks.Add(
Task.Factory.StartNew(() => doNng.DoNothing(canToken), canToken)
.ContinueWith(_ => { Console.WriteLine(..);
}, TaskContinuationOptions.OnlyOnCanceled)
相反,我在DoNothing()例程中的以下行获得了一个异常:
这是出乎意料的。
任何人都可以解释???
完整代码:
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace TestAsync
{
class Program
{
private static readonly SemaphoreSlim Broker = new SemaphoreSlim(3);
static void Main(string[] args)
{
var doNothingTasks = new List<Task>();
using (var cancel = new CancellationTokenSource())
{
var canToken = cancel.Token;
for (var i = 0; i < 10; ++i)
{
var doNng = new TestCancellationToken(i);
doNothingTasks.Add(
Task.Factory.StartNew(() =>
doNng.DoNothing(canToken), canToken)
.ContinueWith(_ => { Console.WriteLine(
$"{DateTime.Now:HH:mm:ss.ffff}. " +
$"{new string('.', 25)} {doNng.Name} " +
$"WAS CANCELLED {new string('.', 10)}");
}, TaskContinuationOptions.OnlyOnCanceled)
);
}
Thread.Sleep(3000);
cancel.Cancel();
try
{
Task.WaitAll(doNothingTasks.ToArray());
}
catch (AggregateException ae)
{
var fae = ae.Flatten();
foreach (var ex in fae.InnerExceptions)
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ffff}. " +
$"{ex.GetType().Name}: {ex.Message}");
}
Console.WriteLine("Done.");
Console.ReadKey();
}
}
class TestCancellationToken
{
private readonly Random _rnd;
public int Name { get; }
public TestCancellationToken(int inx)
{
_rnd = new Random(inx);
Name = inx;
}
public void DoNothing(CancellationToken canToken)
{
for (var i = 0; ; ++i)
{
if (canToken.IsCancellationRequested)
canToken.ThrowIfCancellationRequested();
Broker.Wait();
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ffff}. " +
$"Test {Name} round: {i}, aquire time");
var sleepPeriod = _rnd.Next(750) + 50;
Thread.Sleep(sleepPeriod);
Broker.Release();
Console.WriteLine($"{DateTime.Now:HH:mm:ss.ffff}. " +
$"Test {Name} round: {i}, release time: {sleepPeriod}");
}
}
}
}
}