private void WriteLockLogs() { if (_pendingWrites.IsEmpty) { return; } bool writeHeader = false; if (LogFilePath == null) { LogFilePath = Path.Combine(LogPath, String.Format("LockTimer-{0:yyyy-MM-dd--T--HH-mm-ss}.log", DateTime.Now)); writeHeader = true; } var contention = Contention; using (var fileWriter = File.Open(LogFilePath, FileMode.Append, FileAccess.Write, FileShare.Read)) { using (var streamWriter = new StreamWriter(fileWriter, Encoding.UTF8)) { if (writeHeader) { streamWriter.WriteLine("TimeStart,ThreadId,ThreadName,LockName,LockHash,LockTaken,EnterTotal,InsideTotal,GrandTotal,PreEnter,PostEnter,PreExit,PostExit"); } LockTimer timer; while (_pendingWrites.TryDequeue(out timer)) { var frequencyMilliseconds = Stopwatch.Frequency / 1000; timer._preEnter /= frequencyMilliseconds; timer._postEnter /= frequencyMilliseconds; timer._preExit /= frequencyMilliseconds; timer._postExit /= frequencyMilliseconds; var enterTotal = timer._postEnter - timer._preEnter; var insideTotal = timer._preExit - timer._postEnter; var grandTotal = timer._postExit - timer._preEnter; if (contention != null) { var args = new LockTimerEvent(timer._threadName, timer._name, enterTotal, grandTotal); ThreadPool.QueueUserWorkItem(o => contention(null, args)); } var line = String.Join(",", timer._start.ToString("yyyy-MM-dd HH:mm:ss.ffff"), timer._threadId, timer._threadName.Replace(",", "").Replace("\"", ""), timer._name.Replace(",", "").Replace("\"", ""), timer._syncHash.ToString("x"), timer._lockTaken ? 1 : 0, enterTotal, insideTotal, grandTotal, timer._preEnter, timer._postEnter, timer._preExit, timer._postExit); streamWriter.WriteLine(line); } } } }