2011-03-17 24 views
0

我開始使用屬性,本例中的代碼是使用PostSharp 2.0編寫的。無論如何要從屬性中提取或保存數據嗎?

我想要做的是具有Stopwatch屬性或調用方法可以訪問經過時間的方法。

我使用C#4.0

樣本屬性代碼目前正在寫這個代碼:

[Serializable] 
public class StopwatchAttribute : OnMethodBoundaryAspect 
{ 
    public override void OnEntry(MethodExecutionArgs args) 
    { 
     // Create new stopwatch 
     Stopwatch stopwatch = new Stopwatch(); 

     // Begin timing 
     stopwatch.Start(); 

     args.MethodExecutionTag = stopwatch; 
    } 

    public override void OnExit(MethodExecutionArgs args) 
    { 
     Stopwatch stopwatch = (Stopwatch)args.MethodExecutionTag; 

     // Stop timing 
     stopwatch.Stop(); 

     // Write result 
     Debug.WriteLine("Time elapsed: {0} ms", stopwatch.Elapsed); 
    } 
} 

使用屬性

[Stopwatch] 
public string Search(string LineNo) 
{ 
    // Search for something 
    // Is it possible to know how long (from Stopwatch attribute) Search took 
} 

public void CallSearch 
{ 
    string x = Search("xyz"); 
    // Is it possible to know how long (from Stopwatch attribute) Search took 
} 

我得到的剩餘時間的輸出。

但是,是否有延長這一點,以便我可以發送經過的時間。

理想我想看看多久SearchCallSearch了,但是這將是確定的,如果我可以,即使在Search得到的結果本身,然後以某種方式返回。

作爲解決方法,我目前使用"Hole in the Middle"模式。

謝謝

+1

我一直使用做了類似的事情[團結攔截(http://pnpguidance.net/Post/UnityInterceptionExtensionExampleTransparentProxyPolicyInjectorHandlerAttributeICallHandler.aspx) – 2011-03-17 18:00:07

+0

@Sanjeevakumar我很抱歉,我無法理解你提供的鏈接是如何做什麼,我期待的。你能否提供更多細節。 – 2011-03-20 00:24:06

回答

1

我相信屬性是隻讀的,並在編譯時完全確定。在編譯代碼後,您不能影響屬性。也許你可以保留一個靜態字典(映射代表或MemberInfo執行時間值)跟蹤每個方法的最後執行時間被標記爲跟蹤其執行時間?

+0

感謝您的建議。 – 2011-03-17 20:42:24

1

那麼,方法結束後,屬性中的變量將不再存在。爲了做到這一點,您需要評估數據的日誌或其他持久性來源。您可以將數據寫入靜態List或類似的東西,但是沒有可編寫的代碼可以反射性地檢查屬性本身以確定使用該屬性的方法的最後一次運行需要多長時間(除非屬性類具有一個方法檢查相同的持久存儲)。

正如你所寫的,這個屬性只是一個CLR以特殊方式使用的類;它檢查是否存在面向方面的屬性,根據需要實例化任何,並根據需要調用任何處理程序。這個類只在運行時需要的範圍內,一旦不是,它就是GCed。要使用其面向方面目的範圍之外的屬性,可以使用其類型,和/或使用激活器創建它的新實例。

有一件事;屬性可以具有靜態屬性。因此,您可以定義一個靜態Stopwatch實例,並將其設置爲您最近在OnExit中停止的Stopwatch。這將允許您靜態確定使用該屬性修飾的上次執行方法的時間。

+0

感謝您的建議。我會嘗試創建一個Static屬性,看看我是否可以通過它。 – 2011-03-17 20:41:50

0

可能的解決方案(對不起,我沒有測試它,但這個想法必須明確):

[Serializable] 
public class StopwatchAttribute : OnMethodBoundaryAspect 
{ 
    [ThreadStatic] 
    private static Stopwatch stopwatch = null; 

    public override void OnEntry(MethodExecutionArgs args) 
    { 
     var sw = stopwatch ?? new Stopwatch(); 
     args.MethodExecutionTag = sw; // Better to move this line before .Start 
     sw.Start(); 
    } 

    public override void OnExit(MethodExecutionArgs args) 
    { 
     var sw = (Stopwatch) args.MethodExecutionTag; 
     sw.Stop(); 
     Debug.WriteLine("Time elapsed: {0} ms", sw.Elapsed); 
    } 

    public static Stopwatch Measure(Action action) 
    { 
     var oldStopwatch = stopwatch; 
     stopwatch = new Stopwatch(); 
     try { 
      // !!! Btw, you can measure everything right here. 
      action.Invoke(); 
      return stopwatch; 
     } 
     finally { 
      stopwatch = oldStopwatch; 
     } 
    } 
} 

隱含的用途:

[Stopwatch] 
public string Search(string LineNo) 
{ 
    // Search for something 
    // Is it possible to know how long (from Stopwatch attribute) Search took 
} 

public void CallSearch 
{ 
    var stopwatch = StopwatchAttribute.Measure(() => { 
     string x = Search("xyz"); 
    }); 
    Console.WriteLine("Time elapsed: {0} ms", stopwatch.Elapsed); 
} 

所以你看,PostSharp使用似乎不是這裏非常必要。它可以用於記錄此類時間,但您必須使用類似的方法或您自己的日誌訪問API來獲取記錄的時間。

+0

是的,這或多或少地使用「中間孔」模式。我試圖用屬性來做到這一點主要是作爲一個學習過程。 – 2011-03-17 20:39:40

0

屬性應該只用於在設計時向類,屬性和方法添加描述,然後可以通過反射在運行時檢查這些描述。

我不會用它來存儲業務邏輯。

這是great article供您參考。

相關問題