/// <summary> /// Marks this operation as timed-out, callbacks with the exception /// and sets a handler when the response is received /// </summary> public bool MarkAsTimedOut(OperationTimedOutException ex, Action onReceive) { var previousState = Interlocked.CompareExchange(ref _state, StateTimedout, StateInit); if (previousState != StateInit) { return(false); } //When the data is received, invoke on receive callback var callback = Interlocked.Exchange(ref _callback, (_, __) => onReceive()); #if !NETCORE Thread.MemoryBarrier(); #else Interlocked.MemoryBarrier(); #endif _timeoutCallbackSet = true; Task.Factory.StartNew(() => callback(ex, null), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); return(true); }
private void OnTimeout(object stateObj) { var streamId = (short)stateObj; OperationState state; if (!_pendingOperations.TryGetValue(streamId, out state)) { return; } var ex = new OperationTimedOutException(Address, state.TimeoutMillis); //Invoke if it hasn't been invoked yet //Once the response is obtained, we decrement the timed out counter var timedout = state.MarkAsTimedOut(ex, () => Interlocked.Decrement(ref _timedOutOperations)); if (!timedout) { //The response was obtained since the timer elapsed, move on return; } //Increase timed-out counter Interlocked.Increment(ref _timedOutOperations); }