Sto eseguendo alcuni I/O di rete asincroni utilizzando i metodi di stile Begin/End. (In realtà è una query su Azure Table Storage, ma non penso che importi.) Ho implementato un timeout lato client usando lo ThreadPool.RegisterWaitForSingleObject()
. Funziona bene per quanto posso dire.C#: utilizzo di RegisterWaitForSingleObject se l'operazione viene completata per la prima volta
Perché ThreadPool.RegisterWaitForSingleObject()
prende un WaitHandle
come argomento, devo iniziare l'operazione di I/O, quindi eseguire ThreadPool.RegisterWaitForSingleObject()
. Sembra che questo introduca la possibilità che l'I/O completi prima ancora di registrare l'attesa.
Un esempio di codice semplificato:
private void RunQuery(QueryState queryState)
{
//Start I/O operation
IAsyncResult asyncResult = queryState.Query.BeginExecuteSegmented(NoopAsyncCallback, queryState);
//What if the I/O operation completes here?
queryState.TimeoutWaitHandle = ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, QuerySegmentCompleted, asyncResult, queryTimeout, true);
}
private void QuerySegmentCompleted(object opState, bool timedOut){
IAsyncResult asyncResult = opState as IAsyncResult;
QueryState state = asyncResult.AsyncState as QueryState;
//If the I/O completed quickly, could TimeoutWaitHandle could be null here?
//If so, what do I do about that?
state.TimeoutWaitHandle.Unregister(asyncResult.AsyncWaitHandle);
}
Qual è il modo corretto di gestire questa situazione? Devo ancora preoccuparmi di Unregister()
di AsyncWaitHandle? Se è così, c'è un modo abbastanza semplice per aspettare che venga impostato?
Avete provato a inserire un 'Thread.Sleep' nel mezzo per consentire il completamento dell'operazione di I/O e vedere cosa succede? – mellamokb
Non ho. Penso di averlo visto accadere solo forse 3-4 volte, e poi solo su macchine di produzione pesantemente caricate. Preferisco non iniziare ad aggiungere le chiamate Sleep() al mio vero codice. –
Provalo nel tuo ambiente di sviluppo, ovviamente. Quando dici che hai visto accadere solo 3-4 volte, che cosa hai visto accadere? Una NullPointerException casuale e inspiegabile? – mellamokb