/// <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;
            }
        }
Example #2
0
        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;
            }
        }