Due domande sul assicurando EndInvoke () viene chiamato su un elenco di oggetti IAsyncResult

StackOverflow https://stackoverflow.com/questions/3036921

  •  27-09-2019
  •  | 
  •  

Domanda

Quindi, questa domanda è per quanto riguarda la progettazione del modello Net IAsyncResult e la necessità di chiamare EndInvoke come coperta di questa domanda

Sfondo

Ho qualche codice in cui sto sparando potenzialmente molte chiamate asincrone ad una particolare funzione e quindi in attesa per tutte queste chiamate a finire prima di utilizzare EndInvoke() per tornare tutti i risultati.

Domanda 1

Non so se qualcuno di chiamate ha rilevato un'eccezione fino a quando ho chiamata EndInvoke() e nel caso in cui si verifica un'eccezione in una delle chiamate l'intero metodo dovrebbe fallire e l'eccezione viene avvolto in un'eccezione API specifica e gettato verso l'alto.

Quindi la mia prima domanda è che cosa è il modo migliore quindi per garantire che il resto delle chiamate asincrone ottenere terminato correttamente?

E 'un blocco finally che chiama EndInvoke() sul resto delle chiamate non terminati (e ignora eventuali ulteriori eccezioni) il modo migliore per fare questo?

Domanda 2

In secondo luogo, quando ho il fuoco fuori tutte le mie chiamate ASYC Ho poi chiamo WaitHandle.WaitAll() sul array di istanze WaitHandle che ho dai miei casi IAsyncResult. Il metodo che sta sparando tutte queste chiamate asincrone ha un timeout di aderire al modo fornisco questo al metodo WaitAll(). Test Poi ho fatto tutte le chiamate hanno completato, se non allora il timeout deve essere raggiunta in modo che il metodo deve anche fallire e lanciare un'altra eccezione API specifica.

Quindi la mia seconda domanda è che cosa devo fare in questo caso?

ho bisogno di chiamare EndInvoke() per terminare tutte queste chiamate asincrone prima che mi passi l'errore, ma allo stesso tempo non voglio che il codice di rimanere bloccati in quanto EndInvoke() sta bloccando. Almeno in teoria, se la chiamata WaitAll() volte fuori allora tutte le chiamate asincrone dovrebbero si sono scaduta e le eccezioni gettato (completando così la chiamata) in quanto sono regolate anche da un timeout, ma questo timeout è potenzialmente diverso dal timeout principale

È stato utile?

Soluzione

Vorrei scorrere gli oggetti IAsyncResult, avvolgendo ogni EndInvoke in un try / catch che memorizza qualsiasi generato l'eccezione da qualche altra parte. Poi, quando hai chiamato tutti i EndInvokes, si può vedere se hai memorizzato eventuali eccezioni e un'eccezione API in caso affermativo. Qualcosa di simile:

var exs = new List<Exception>();

foreach (IAsyncResult iasr in asyncResults) {
    try {
        iasr.EndInvoke();
    }
    catch (Exception e) {
        exs.Add(e);
    }
}

if (exs.Count > 0) {
    throw new MyException(exs.ToReadOnly());
}

Altri suggerimenti

I consiglia di utilizzare Compiti invece di IAsyncResult, se possibile. Hanno belli semantica "continuazione", e possono avvolgere un'API IAsyncResult, chiamando EndInvoke in modo appropriato per voi.

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