I have a very very strange problem, and here's my codes now:
namespace TaskParallelTest
{
using System.Threading;
using System.Threading.Tasks;
using System;
using System.IO;
public class Program
{
static Program()
{
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}
private static void DoPrint(int id, CancellationToken cToken)
{
Thread.Sleep(100);
if (!cToken.IsCancellationRequested)
{
Console.WriteLine("Id is:" + id + ";Current State:" + cToken.IsCancellationRequested);
cToken.Register(() => Console.WriteLine("Rollback for:" + id));
}
}
static void Main(string[] args)
{
CancellationTokenSource cTokenSource = new CancellationTokenSource();
Task.Run(() =>
{
for (int i = 1; i < 6; i++)
{
cTokenSource.Token.ThrowIfCancellationRequested();
DoPrint(i, cTokenSource.Token);
}
}, cTokenSource.Token);
Random r = new Random();
Thread.Sleep(400);
cTokenSource.Cancel(true);
Thread.Sleep(10000);
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine("OK");
Console.ReadLine();
}
private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
File.WriteAllText("C:\\Resume\\Error.txt", e.Exception.StackTrace);
e.SetObserved();
}
}
}
What makes me feel mad is why the event of "UnobservedTaskException" cannot be caught? I used GC.Collect() and Thread.Sleep(), but without any help……?
Sometimes, the "Error.txt" wasn't created, and sometimes, the file created without anything there....?
【Solved——Now acording to the suggestions, here's the answer】
1) Notice that I should remove "Cancellation" and mock an exception here:
static void Main(string[] args)
{
CancellationTokenSource cTokenSource = new CancellationTokenSource();
Task.Run(() =>
{
for (int i = 1; i < 6; i++)
{
if (i==5)
{
throw new Exception("Error occured!");
}
DoPrint(i, cTokenSource.Token);
}
},cTokenSource.Token)
.ContinueWith
(
t =>
{
Console.WriteLine("Error has happened now.");
Console.WriteLine(t.IsFaulted);
},
TaskContinuationOptions.OnlyOnFaulted
);
Thread.Sleep(400);
//cTokenSource.Cancel();
//Thread.Sleep(2000);
GC.Collect();
GC.WaitForPendingFinalizers();
//Thread.Sleep(6000);
Console.WriteLine("OK");
Console.ReadLine();
}
2) Then flatten the Exception (because's that an aggregative exception):
private static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
foreach (var item in e.Exception.Flatten().InnerExceptions)
{
Console.WriteLine(item.StackTrace);
}
e.SetObserved();
}