Robię niektóre asynchroniczne operacje we/wy sieci przy użyciu metod stylu Początek/Koniec. (W rzeczywistości jest to zapytanie przeciwko Azure Table Storage, ale nie sądzę, aby to miało znaczenie.) Zaimplementowałem limit czasu po stronie klienta, używając ThreadPool.RegisterWaitForSingleObject()
. Działa to dobrze, o ile wiem.C#: Używanie RegisterWaitForSingleObject, jeśli operacja zakończy się po raz pierwszy
Ponieważ ThreadPool.RegisterWaitForSingleObject()
pobiera WaitHandle
jako argument, muszę rozpocząć operację I/O, a następnie wykonać ThreadPool.RegisterWaitForSingleObject()
. Wydaje się, że to wprowadza możliwość, że I/O kończy się, zanim jeszcze zarejestruję czekanie.
Uproszczony przykładowy kod:
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);
}
Jaki jest właściwy sposób, aby sobie z tym poradzić? Czy nadal muszę się martwić o Unregister()
"AsyncWaitHandle? Jeśli tak, czy istnieje dość łatwy sposób, aby czekać na jego ustawienie?
Czy próbowałeś wstawić 'Thread.Sleep' w środku, aby dać czas na zakończenie operacji I/O i zobaczyć, co się stanie? – mellamokb
Nie mam. Myślę, że widziałem to tylko 3-4 razy, a potem tylko na mocno obciążonych maszynach produkcyjnych. Wolałbym nie dodawać wywołań Sleep() do mojego prawdziwego kodu. –
Sprawdź oczywiście w swoim środowisku programistycznym. Kiedy mówisz, że widziałeś to zdarzenie tylko 3-4 razy, co się stało? Losowy niewyjaśniony wyjątek NullPointerException? – mellamokb