为什么从Task引发的异常被视为已取消(即使我没有按'x'来取消它)却没有被视为有故障? 以下代码的输出是:
Press 'x' to cancel
Job has been canceled
Task has been canceled
Press Enter to exit
代码
static void Main(string[] args)
{
try
{
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
var jobTask = Task.Run(() =>
{
if (cancellationToken.IsCancellationRequested)
cancellationToken.ThrowIfCancellationRequested();
while (true)
{
if (cancellationToken.IsCancellationRequested)
cancellationToken.ThrowIfCancellationRequested();
Thread.Sleep(2000);
if (cancellationToken.IsCancellationRequested)
cancellationToken.ThrowIfCancellationRequested();
throw new Exception("Test Exception");
}
}, cancellationToken)
.ContinueWith((t) =>
{
Console.WriteLine("Job has been completed");
}, TaskContinuationOptions.OnlyOnRanToCompletion)
.ContinueWith((t) =>
{
Console.WriteLine("Job has been canceled");
}, TaskContinuationOptions.OnlyOnCanceled)
.ContinueWith((t) =>
{
Console.WriteLine("Exception thrown: {0}", t.Exception.InnerException);
}, TaskContinuationOptions.OnlyOnFaulted);
Task.Run(() =>
{
Console.WriteLine("Press 'x' to cancel");
while (Console.ReadKey(true).KeyChar != 'x')
{
Thread.Sleep(200);
}
cancellationTokenSource.Cancel();
});
try
{
jobTask.Wait();
}
catch (AggregateException ex)
{
foreach (var v in ex.InnerExceptions)
{
if (v is TaskCanceledException)
Console.WriteLine("Task has been canceled");
else
Console.WriteLine("Exception: {0} - {1}", v.GetType().Name, v.InnerException);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: {0}", ex.Message);
}
}
catch (Exception ex)
{
Console.WriteLine("E - {0}", ex.Message);
}
Console.WriteLine("Press Enter to exit");
Console.ReadKey();
}
}
答案 0 :(得分:1)
Task.ContinueWith
方法返回一个代表继续的新Task
对象。如果不满足continuationOptions
参数中指定的条件,则取消继续任务。
您的代码将对continueWith
的三个调用链接在一起。这实际上创建了四个任务:
Task
用于传递给Task.Run
的委托执行,两秒钟后引发异常Task
成功完成后才运行的第一个延续Task
Task
Task
引发异常时,第一个Task
错误,第一个继续被取消,因为它继续执行的Task
未成功完成,第二个继续运行,因为第一个继续被取消,并且第三个延续被取消,因为第二个延续没有错。
try块正在Wait
上调用jobTask
,该Task
保留了第三连续的public interface ProgrammationRepository extends JpaRepository<Programmation, Long> {
@Query("select programmation from Programmation programmation left join fetch programmation.film where programmation.dateprogrammation >= ?#{@ProgrammationRepository.addSixDay()} and programmation.dateprogrammation <= ?#{@ProgrammationRepository.addSevenDay()}")
List<Programmation> getSevenNextDay();
@Query("select programmation from Programmation programmation left join fetch programmation.film where programmation.film.id = :id")
List<Programmation> getFindByFilm(@Param("id") Long id);
default Instant addSixDay() {
System.out.println( Instant.now().plus(6, ChronoUnit.DAYS));
return Instant.now().minus(6, ChronoUnit.DAYS);
}
default Instant addSevenDay() {
return Instant.now().plus(7, ChronoUnit.DAYS);
}
,该连续总是被取消。
Microsoft文档参考:Task.ContinueWith