2011-03-17 5 views
0

Je commence à travailler avec des attributs et pour cet exemple le code est écrit en utilisant PostSharp 2.0.Est-il possible d'extraire ou de sauvegarder des données d'un attribut?

Ce que je voudrais faire est la méthode qui a l'attribut Stopwatch ou la méthode d'appel peut accéder au temps écoulé.

Je vous écris actuellement ce code en C# 4.0

code d'attribut Exemple:

[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); 
    } 
} 

En utilisant l'attribut

[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 
} 

Je reçois une sortie de temps écoulé.

Cependant, est-il possible de prolonger ceci afin que je puisse envoyer le temps écoulé.

Idéalement je voudrais voir combien de temps Search a pris de CallSearch, mais ce sera ok si je peux même obtenir le résultat dans Search lui-même, puis revenir en quelque sorte elle.

Pour contourner le problème, j'utilise actuellement le modèle "Hole in the Middle".

Merci

+1

je l'avais fait chose similaire en utilisant [Unité Interception] (http://pnpguidance.net/Post/UnityInterceptionExtensionExampleTransparentProxyPolicyInjectorHandlerAttributeICallHandler.aspx) –

+0

@Sanjeevakumar Je suis désolé, je ne pouvais pas comprendre comment le lien fournies par votre fait ce que je cherche. Pourriez-vous s'il vous plaît fournir plus de détails. –

Répondre

1

je crois que les attributs sont en lecture seule et entièrement déterminés au moment de la compilation. Vous ne pouvez pas affecter les attributs après la compilation du code. Peut-être pourriez-vous garder un dictionnaire statique (mappant les délégués ou MemberInfo aux valeurs de temps d'exécution) pour suivre la dernière heure d'exécution de chaque méthode marquée pour suivre son temps d'exécution?

+0

Merci pour la suggestion. –

1

Eh bien, les variables de l'attribut cesseront d'exister après la fin de la méthode. Pour ce faire, vous devez évaluer le journal ou une autre source persistante pour les données. Vous pouvez écrire des données dans une liste statique ou quelque chose comme ça, mais il n'y a pas de code que vous pouvez écrire pour examiner l'attribut lui-même afin de déterminer la durée de la dernière exécution de la méthode avec cet attribut. examine le même magasin persistant). L'attribut, comme vous l'avez écrit, est juste une classe qui est utilisée d'une manière spéciale par le CLR; Il vérifie la présence d'attributs orientés aspect, instancie les attributs nécessaires et appelle les gestionnaires si nécessaire. La classe est seulement dans la portée alors qu'elle est nécessaire pour l'exécution, et une fois qu'elle ne l'est pas, elle est GCed. Pour utiliser un attribut en dehors de son objectif orienté aspect, vous travaillez avec son type et/ou créez une nouvelle instance à l'aide de l'activateur.

Une chose; Un attribut peut avoir des propriétés statiques. Ainsi, vous pouvez définir une instance Stopwatch statique et la définir sur le Stopwatch que vous avez le plus récemment arrêté dans OnExit. Cela vous permettrait de déterminer statiquement l'heure de la dernière méthode exécutée décorée avec l'attribut.

+0

Merci pour la suggestion. Je vais essayer de créer une propriété statique et voir si je peux travailler à travers cela. –

0

Solution possible (désolé, je ne l'ai pas testé, mais l'idée doit être claire):

[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; 
     } 
    } 
} 

utilisation Implicite:

[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); 
} 

Comme vous le voyez, l'utilisation PostSharp ne semble pas tout à fait nécessaire ici.Il peut être utilisé pour consigner ces horaires, mais vous devez utiliser une approche similaire ou votre propre API d'accès au journal pour obtenir l'heure de connexion.

+0

Oui, c'est plus ou moins en utilisant le motif "Hole in the MIddle". J'essaye de faire ceci avec des attributs principalement comme processus d'étude. –

0

Les attributs ne doivent être utilisés que pour ajouter des descriptions aux classes, aux propriétés et aux méthodes au moment du design qui peuvent ensuite être examinées à l'exécution via la réflexion. Je ne l'utiliserais pas pour stocker la logique métier.

Voici un great article pour votre référence.

Questions connexes