/// <summary> /// Traces both a begin and an end trace around a specified asynchronous operation. /// </summary> /// <remarks>The end trace will occur when the asynchronous operation completes, either success or failure.</remarks> /// <param name="traceWriter">The <see cref="ITraceWriter"/>.</param> /// <param name="request">The <see cref="HttpRequestMessage"/> with which to associate the trace. It may be null.</param> /// <param name="category">The logical category of the trace.</param> /// <param name="level">The <see cref="TraceLevel"/> of the trace.</param> /// <param name="operatorName">The name of the object performing the operation. It may be null.</param> /// <param name="operationName">The name of the operation being performed. It may be null.</param> /// <param name="beginTrace">The <see cref="Action"/> to invoke prior to performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="execute">An <see cref="Func{Task}"/> that returns the <see cref="Task"/> that will perform the operation.</param> /// <param name="endTrace">The <see cref="Action"/> to invoke after successfully performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <param name="errorTrace">The <see cref="Action"/> to invoke if an error was encountered performing the operation, /// allowing the given <see cref="TraceRecord"/> to be filled in. It may be null.</param> /// <returns>The <see cref="Task"/> returned by the operation.</returns> public static Task TraceBeginEndAsync(this ITraceWriter traceWriter, HttpRequestMessage request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task> execute, Action <TraceRecord> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw System.Web.Http.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw System.Web.Http.Error.ArgumentNull("execute"); } traceWriter.Trace( request, category, level, (TraceRecord traceRecord) => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task task = execute(); // If the operation returned a null Task, we cannot do any // further tracing. Return that null to the caller as // would happen if tracing were not enabled. if (task == null) { return(task); } return(traceWriter.TraceBeginEndAsyncCore(request, category, level, operatorName, operationName, endTrace, errorTrace, task)); } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }
public static Task <TResult> TraceBeginEndAsync <TResult>(this ITraceWriter traceWriter, HandlerRequest request, string category, TraceLevel level, string operatorName, string operationName, Action <TraceRecord> beginTrace, Func <Task <TResult> > execute, Action <TraceRecord, TResult> endTrace, Action <TraceRecord> errorTrace) { if (traceWriter == null) { throw Internal.Error.ArgumentNull("traceWriter"); } if (execute == null) { throw Internal.Error.ArgumentNull("execute"); } Stopwatch stopwatch = Stopwatch.StartNew(); traceWriter.Trace( request, category, level, traceRecord => { traceRecord.Kind = TraceKind.Begin; traceRecord.Operator = operatorName; traceRecord.Operation = operationName; if (beginTrace != null) { beginTrace(traceRecord); } }); try { Task <TResult> task = execute(); // If the operation returned a null Task, we cannot do any // further tracing. Return that null to the caller as // would happen if tracing were not enabled. if (task == null) { return(null); } return(traceWriter.TraceBeginEndAsyncCore(request, category, level, operatorName, operationName, stopwatch.Elapsed, endTrace, errorTrace, task)); } catch (Exception exception) { traceWriter.TraceError(exception, request, category, operatorName, operationName, errorTrace); throw; } }