2009-03-13 23 views
7

Ho una chiamata asincrona al metodo beexecutereader di comando sql, che un utente può annullare. Quando si verifica l'annullamento, annullo l'oggetto sqlcommand e questo ucciderebbe il lavoro in esecuzione su SQL Server.Rilevamento comando annullato in BeginExecuteReader asincrono

Tuttavia, non appena lo annullo, viene richiamato il metodo di callback specificato nella query BeginExecute e viene eliminato quando si tenta di chiamare endexecutequery. Il risultato. Completato è vero, fino a quando viene chiamata la query endexecute, a quel punto diventa falso.

C'è un modo per rilevare nel metodo di richiamata che il comando è annullato? o devo per tenere traccia di quello ...

grazie

risposta

8

ho cancellato e riavviato tutta la mia risposta: quando hai inciampato su un buon caso di documentazione contraddittoria e le avvertenze ...

Secondo il .NET 2.0 MSDN Documentation for the SqlCommand.Cancel "Il metodo Cancel non può essere utilizzato per annullare un asincrona in attesa operazione." Tuttavia, la stessa documentazione per .NET 3.5 non contiene questo avviso, nonostante sia altrimenti identico alla documentazione 2.0.

Vorrei consigliare seguendo le convenzioni delineate in Calling Synchronous Methods Asynchronously che è indirizzato a Delegate.BeginInvoke (non Control.BeginInvoke!) E Delegate.EndInvoke, ma è probabilmente rilevante nel tuo caso.

I metodi denominati "Begin ... Async" che restituiscono un IAsyncResult e hanno un corrispondente metodo "End ..." possono potenzialmente creare una perdita ThreadPool. Il modo più semplice per prevenire perdite è assicurarsi che venga sempre chiamato il metodo "Fine ..." corrispondente.

Il motivo è che quando Begin ... Async viene chiamato riceve un thread dal ThreadPool e (in genere) esegue la versione sincrona del metodo sul thread di lavoro; nel tuo caso ExecuteReader(). Il valore di ritorno di quella chiamata, o eventuali eccezioni che si verificano durante quella chiamata, non vengono riportati al thread principale finché End ... viene chiamato - se non si chiama End, i risultati/le eccezioni non vengono mai restituiti e il thread ThreadPool non è mai stato liberato.

Per farla breve, è probabile che sia sicuro finché si è sicuri di chiamare EndExecuteReader() e gestire l'eccezione prevista. Dal momento che la documentazione è contraddittoria e vaga, ho iniziato un discussion on the MSDN Feedback Forums.

+0

State cercando di capire come annullare un'operazione SQL a esecuzione prolungata in modo asincrono, e questa è l'unica risposta che ha funzionato per me. Grazie! – Porkbutts

Problemi correlati