Domanda

static async void Main(string[] args)
{
    Task t = new Task(() => { throw new Exception(); });

    try
    {                
        t.Start();
        t.Wait();                
    }
    catch (AggregateException e)
    {
        // When waiting on the task, an AggregateException is thrown.
    }

    try
    {                
        t.Start();
        await t;
    }
    catch (Exception e)
    {
        // When awating on the task, the exception itself is thrown.  
        // in this case a regular Exception.
    }           
}

In TPL, quando si lancia un'eccezione all'interno di un'attività, è avvolta da un Exception Aggregate.
Ma lo stesso non sta accadendo quando si usa il Aspetta parola chiave.
Qual è la spiegazione di quel comportamento?

È stato utile?

Soluzione

L'obiettivo è farlo sembrare/agire come la versione sincrona. Jon Skeet fa un ottimo lavoro spiegando questo nella sua serie Eduasync, in particolare questo post:

http://codeblog.jonskeet.uk/2011/06/22/eduasync-part-11-more-sopicato-but-lossy-exception-handling/

Altri suggerimenti

In TPL AggregateException viene utilizzato perché è possibile avere più attività nell'operazione di attesa (l'attività può avere attività per bambini allegate), quindi molte di esse possono lanciare eccezioni. Guarda a Eccezioni nei compiti di bambini Sezione qui:

https://msdn.microsoft.com/ru-ru/library/dd997417(v=vs.110).aspx

In await Hai sempre solo un compito.

Guarda anche https://msdn.microsoft.com/ru-ru/library/dd997415(v=vs.110).aspx

Ecco una buona spiegazione nei dettagli, di Stephen Toub, perché c'è una differenza nel tipo di eccezione tra l'attività.Wait () e l'attesa:

Task Eccezioni gestite in .NET 4.5

Durante la progettazione di task.ait in .NET 4, abbiamo scelto di propagare sempre un aggregato. Tale decisione è stata influenzata dalla necessità di non sovrascrivere i dettagli, ma anche dal caso d'uso primario per le attività all'epoca, quella del parallelismo fork/join, in cui il potenziale per le eccezioni multiple è abbastanza comune.

Sebbene simile a Task.avere ad alto livello (cioè i progressi in avanti non vengono compiuti fino al completamento dell'attività), "Attesa dell'attività" rappresenta un insieme primario molto diverso di scenari. Invece di essere utilizzato per il parallelismo fork/join, l'uso più comune di "Abswit Task" è quello di prendere un pezzo di codice sequenziale e sincrono e trasformarlo in un pezzo di codice sequenziale e asincrono. In luoghi nel tuo codice in cui si esegue un'operazione sincrona, lo sostituisci con un'operazione asincrona rappresentata da un'attività e "si aspetta". Pertanto, mentre puoi certamente usare l'attesa per le operazioni di forcella/join (ad es. Utilizzo dell'attività. Inoltre, .NET 4.5 vede l'introduzione di System.Runtime.ExcectionServices.ExceptionDispatchInfo, che risolve il problema di consentire di fare il maresciallo attraverso i thread senza perdere dettagli di eccezione come Stack Trace e Watson Buckets. Dato un oggetto di eccezione, lo passiamo a ExceptionDispatchInfo.Create, che restituisce un oggetto ExceptionDisPatchInfo che contiene un riferimento all'oggetto di eccezione e una copia dei suoi dettagli. Quando è il momento di lanciare l'eccezione, l'eccezione che il metodo di lancio di DispatchInfo viene utilizzato per ripristinare il contenuto dell'eccezione e lanciarlo senza perdere le informazioni originali (le informazioni di Call Stack corrente vengono aggiunte a ciò che è già memorizzato nell'eccezione).

Detto questo, e di nuovo avere la scelta di lanciare sempre il primo o di lanciare sempre un aggregato, per "aspettare", optiamo di lanciare sempre il primo. Ciò non significa, tuttavia, di non avere accesso agli stessi dettagli. In tutti i casi, la proprietà dell'eccezione dell'attività restituisce ancora un Exception Aggregate che contiene tutte le eccezioni, in modo da poter catturare qualunque cosa venga lanciata e torna indietro per consultare Task.Exception quando necessario. Sì, questo porta a una discrepanza tra il comportamento delle eccezioni quando si passa tra "Task.Wait ()" e "Attesa attività", ma l'abbiamo visto come il significativo minore di due mali.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top