2017-04-15 54 views
0

我需要用许多日志记录信息(时间等)来实现记录某些方法的调用。我可以这样做:记录操作,如何实现更好

var stopwatch = new Stopwatch(); 
OCRResult ocrResult = await ocr.GetTextAsync(dataStream, filename, language); 
stopwatch.Stop(); 
// log here, with time, result etc 

它会工作,但我不喜欢这种方法。首先,我在很多地方都有很多这样的电话,而且我需要公开代码。其次,这种方法违反了SRP(单一责任原则),每个电话都有一项工作。我需要做一个包装或使用策略模式,无论如何我应该创建一个类来做到这一点。但是如何实现呢?

+1

像PostSharp之类的东西可以为您注入这种方法仪器。如果你的项目很小,你甚至可以免费使用它。 – Crowcoder

+0

看一看[这篇文章](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91),它描述了你如何设计你的应用程序,使它变得微不足道添加横切关注性能分析和日志记录,并阻止使用代码编织工具(如PostSharp)。 – Steven

+1

@Steven只要没有很多继承,就会让Decorator变得笨拙。 – Crowcoder

回答

2

您可以创建一种测量功能的时间,并记录它的通用方法:

public static void LogFunc<T>(Func<T> func) 
{ 
    var stopwatch = Stopwatch.StartNew(); 
    T result = func(); 
    stopwatch.Stop(); 
    long time = stopwatch.ElapsedMilliseconds; 
    // log here, with time, result etc 
} 

LogFunc(async() => await ocr.GetTextAsync(dataStream, filename, language)); 

一个async版本的方法:

public static async Task LogFuncAsync<T>(Func<Task<T>> func) 
{ 
    var stopwatch = Stopwatch.StartNew(); 
    T result = await func(); 
    stopwatch.Stop(); 
    long time = stopwatch.ElapsedMilliseconds; 
    // log here, with time, result etc 
} 

await LogFuncAsync(() => ocr.GetTextAsync(dataStream, filename, language)); 
+0

一个有趣的想法,但调用func()不等待函数的执行。如何正确调用它? –

+0

您可以制作此功能的异步版本。 –

0

遵循“幼狮人”答案是我修改他的回答得到如下结果:

public static async Task LogFuncAsync<T>(Func<Task<T>> func) 
    { 
     var stopwatch = Stopwatch.StartNew(); 
     T result = await func(); 
     stopwatch.Stop(); 
     long time = stopwatch.ElapsedMilliseconds; 
     // log here, with time, result etc 
    } 

并且将其命名为:

await Utils.LogFuncAsync(async() => ocrResult = await ocr.GetTextAsync(dataStream, filename, language)); 
+0

你的回答很好,但你应该编辑我的。 –