2017-04-15 117 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

你的回答很好,但你應該編輯我的。 –