我創建了一個IDisposable對象,用於記錄Dispose上的執行時間。使用異步語句不等待內部任務
然後,我創建了一個使用這個對象來記錄我的業務類的任何方法調用
我的業務類使用異步方法,在任務完成前,然後離開using語句的時間RealProxy ,然後記錄錯誤的執行時間。
這裏是我的代碼:
/// <summary>
/// Logging proxy with stopwatch
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class LoggingProxy<T> : RealProxy// where T : MarshalByRefObject
{
private ILog _logger;
private readonly T _instance;
private LoggingProxy(T instance, ILog logger)
: base(typeof(T))
{
_logger = logger;
_instance = instance;
}
/// <summary>
/// Create the Transparent proy for T
/// </summary>
/// <param name="type">An implementation type of T</param>
/// <returns>T instance</returns>
public static T Create(ILog logger)
{
logger.DebugFormat("[{0}] Instantiate {1}", "LoggingProxy", typeof(T).Name);
var instance = (T)Activator.CreateInstance(typeof(T), logger);
//return the proxy with execution timing if debug enable in logger
if (logger.IsDebugEnabled)
return (T)new LoggingProxy<T>(instance, logger).GetTransparentProxy();
else
return instance;
}
/// <summary>
/// Invoke the logging method using Stopwatch to log execution time
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
public override IMessage Invoke(IMessage msg)
{
var methodCall = (IMethodCallMessage)msg;
var method = (MethodInfo)methodCall.MethodBase;
string methodName = method.Name;
string className = method.DeclaringType.Name;
//return directly methods inherited from Object
if (method.DeclaringType.Name.Equals("Object"))
{
var result = method.Invoke(_instance, methodCall.Args);
return new ReturnMessage(result, null, 0, methodCall.LogicalCallContext, methodCall);
}
using (var logContext = _logger.DebugTiming("[{0}] Execution time for {1}", className, methodName))
{
_logger.DebugFormat("[{0}] Call method {1}", className, methodName);
//execute the method
//var result = method.Invoke(_instance, methodCall.Args);
object[] arg = methodCall.Args.Clone() as object[];
var result = method.Invoke(_instance, arg);
//wait the task ends before log the timing
if (result is Task)
(result as Task).Wait();
return new ReturnMessage(result, arg, 0, methodCall.LogicalCallContext, methodCall);
}
}
的_logger.DebugTiming方法啓動秒錶t和記錄它的處置。 我發現,使其與異步方法的工作的唯一辦法,就是用這條線:
//wait the task ends before log the timing
if (result is Task)
(result as Task).Wait();
但我一直認爲我做的是打破異步方法的所有優點的感覺。
- >如果你有一個關於如何做一個正確實施
建議 - >任何的呼籲代理的wait()的真正影響的想法?
您嘗試編寫的代碼可以在[使用Unity的異步攔截器]中找到(https://msdn.microsoft.com/en-us/magazine/dn574805.aspx) –
但是,在我的上下文中不能使用Unity。 。有些經理將它看作科幻 –