Zdravím, řeším způsob jak nejlépe zpracovat Exceptions, které vzniknou při běhu Task<int>.Factory.StartNew(...). Tento kousek kódu čte seznam zařízení, provádí se s nimi určité operace a updatuje se stav do DB. Kvůli pomalému zpracování jsem použil Task<int>.Factory.StartNew. Teďka ale nejsem schopen zachytit Exception, pokud vznikne chyba - pro závěrečnou sumarizaci: Zařízení 1 | OK | --- Zařízení 2 | ERR | Exception message Zařízení 3 | OK | --- Zařízení 4 | OK | --- Zařízení 5 | ERR | Exception message ...atd. Konstruktor, kde spoustim volani TASKu:
public TaskTest()
{
// get list of devices
List<Device> listDevices = this.myDeviceRepository.GetDevices().ToList();
int intDeviceCounter = 0;
Task<int>[] tasks = new Task<int>[listDevices.Count];
foreach (Device myDevice in listDevices)
{
//int tempId = intDeviceCounter; // Make a temporary here!
tasks[intDeviceCounter] = Task<int>.Factory.StartNew(() => CheckFiles(intDeviceCounter, myDevice));
Thread.Sleep(500); // TODO: bez tohoto muzou vzniknout chyby kvuli ticku (viz. MSDN)
intDeviceCounter++;
}
// Exceptions thrown by tasks will be propagated to the main thread
// while it waits for the tasks. The actual exceptions will be wrapped in AggregateException.
try
{
// Wait for all the tasks to finish.
Task.WaitAll(tasks);
// We should never get to this point
Console.WriteLine("WaitAll() has not thrown exceptions. THIS WAS NOT EXPECTED.");
}
catch (AggregateException e)
{
Console.WriteLine("\nThe following exceptions have been thrown by WaitAll(): (THIS WAS EXPECTED)");
for (int j = 0; j < e.InnerExceptions.Count; j++)
{
Console.WriteLine("\n-------------------------------------------------\n{0}", e.InnerExceptions[j].ToString());
}
}
Console.WriteLine("HOTOVO");
Console.ReadLine();
}
Metoda, kterou volá Task:
private int CheckFiles(int InputID, Device myDevice)
{
//// inner try-catch for each device
try
{
Console.WriteLine(myDevice.strHostName + ":");
// get MyFile object
List<MyFileObject> listMyFilesObject = this.GetMyFiles(myDevice);
// get result
this.GetResult(listMyFilesObject, myDevice);
Console.WriteLine(" - ok");
}
catch (Exception myException)
{
Console.WriteLine(" - " + myException.Message.ToString());
Console.WriteLine(" -- " + myException.ToString());
}
return InputID;
}
Pokud jsem zkusil postupovat dle návodů na MSDN / googlu, že do Task<> dám místo int vlastní objekt, nikdy jsem nebyl schopen získat výše uvedený výsledek/sumarizaci, tj.:
class TaskTestResult
{
public Exception exException { get; set; }
public int intThreadId { get; set; }
}
private TaskTestResult CheckFiles(int InputID, Device myDevice)
...
Task<TaskTestResult>[] tasks = new Task<TaskTestResult>[listDevices.Count];
...
Petr
|