public void Dispose() { var stopwatch = Interlocked.Exchange(ref duration, null); if (stopwatch == null) { return; } stopwatch.Stop(); var span = new Span { TraceId = TraceId, SpanId = SpanId, Name = Name, Resource = Resource, Service = Service, Type = Type, Start = start, Duration = Span.ToNanoseconds(stopwatch.Elapsed), ParentId = null, Error = error, Meta = meta, }; ThreadSafeUtil.ReturnStopwatch(stopwatch); Span[] array; lock (gate) { spans.Add(ref span); array = spans.ToArray(); } manager.EnqueueToWorker(array); }
async Task ConsumeQueue() { var buffer = new StructBuffer <Span[]>(bufferingCount); while (!cancellationTokenSource.IsCancellationRequested) { try { buffer.Clear(); var addCount = 0; for (int i = 0; i < bufferingCount; i++) { Span[] nextTrace; if (q.TryDequeue(out nextTrace)) { addCount++; buffer.Add(ref nextTrace); } else { break; } } if (addCount == 0) { await Task.Delay(bufferingTime).ConfigureAwait(false); } else { var traces = buffer.ToArray(); await client.Traces(traces).ConfigureAwait(false); } } catch (OperationCanceledException) { break; } catch (ObjectDisposedException) { break; } } }