/// <summary> /// Buffers the specified message to be asynchronously logged. /// </summary> /// <param name="message">The message to log.</param> public void Log(string message) { // which period number within the day are we in right now? TimeSpan timeOfDay = AmbientClock.UtcNow.TimeOfDay; int newPeriodNumber = (int)(timeOfDay.TotalMinutes / _rotationPeriodMinutes); int attempt = 0; // loop attempting to update the period number if we need to or until we win the race or timeout while (true) { // get the latest value int oldValue = _periodNumber; // someone beat us to it? if (newPeriodNumber == oldValue) { break; } // try to put in our value--did we win the race? if (oldValue == System.Threading.Interlocked.CompareExchange(ref _periodNumber, newPeriodNumber, oldValue)) { // we won the race to update the period number _fileBuffers.BufferFileRotation(PeriodString(newPeriodNumber) + _fileExtension); break; } // note that it's very difficult to test a miss here--you really have to pound it with multiple threads, so this next line (and the not equal condition on the "if" above are not likely to get covered if (!InterlockedExtensions.TryAgainAfterOptomisticMissDelay(attempt++)) { break; } } if (!_disposedValue) { _fileBuffers.BufferLine(message); } }