2010-12-14 54 views
0

Je crois qu'il s'agit d'une question WCF, mais peut-être aussi liée à Azure. J'ai un projet WCF qui exécute des scripts de fer python. Je voudrais garder un cache des scripts compilés, ils n'auront donc pas besoin d'être recompilés à chaque fois.Création d'un objet global dans le projet Azure WCF

Lorsque ces scripts s'exécutent la première fois, ils peuvent parfois prendre 2 ou 3 secondes. Cependant, la prochaine fois qu'ils s'exécuteront, ils s'exécuteront en quelques millisecondes. Je voudrais mettre en cache la source du script afin qu'elle ne soit compilée qu'une seule fois, puis réutilisée pour tous ceux qui utilisent mon service. Actuellement, mon comportement de service entier est instancié chaque fois que quelqu'un se connecte à mon service. Est-il possible d'avoir mon objet ScriptCache persistant pendant la vie de l'application?

Voici un exemple de code avec lequel je joue.

[ServiceBehavior] 
public class Foo: IFoo { 
    ScriptEngine engine = Python.CreateEngine(); 
    Dictionary<string, ScriptHost> ScriptCache = new Dictionary<string, ScriptHost>(); 
    public fooBar doSomething() { 
     ... 
     for (int editIndex = 0; editIndex < Edits.Count; editIndex++) { 
      ScriptHost mCurrentScript; 
      if (!ScriptCache.TryGetValue(Edits[editIndex], out mCurrentScript)) { 
       mCurrentScript = new ScriptHost(LoadScriptFromStorage(Edits[editIndex]), Edits[editIndex], engine); 
       ScriptCache.Add(Edits[editIndex], mCurrentScript); 
      } 
      mEditTimer.Start(); 
      mCurrentScript.runScript(mCurrentObj); 
      mEditTimer.Stop(); 
      WriteToLog(mJobID, "Edit: {0}\tTime: {1}", Edits[editIndex], mEditTimer.Elapsed.TotalMilliseconds); 
      mEditTimer.Reset(); 
      mEditTimer.Start(); 
      mCurrentScript.runScript(mCurrentObj); 
      mEditTimer.Stop(); 
      WriteToLog(mJobID, "Edit: {0}\tTime: {1}\t2nd run", Edits[editIndex], mEditTimer.Elapsed.TotalMilliseconds); 
      mEditTimer.Reset(); 
      } 
    } 

Répondre

1

La solution la plus simple consiste simplement à marquer les propriétés comme statiques. Je vais deviner qu'il est possible que ce code puisse être appelé en parallèle, donc vous devrez vous assurer que l'ajout au dictionnaire est thread-safe. J'ai inclus un extrait de code ci-dessous. Je remplace l'appel à ScriptCache.Add avec un appel à quelque chose comme la fonction AddToCache ci-dessous

[ServiceBehavior] 
public class Foo : IFoo 
{ 
    static ScriptEngine engine = Python.CreateEngine(); 
    static Dictionary<string, ScriptHost> ScriptCache = new Dictionary<string, ScriptHost>(); 
    static object _dictionaryLock = new object(); 

    static void AddToCache(string edit, ScriptHost host) 
    { 
     lock (_dictionaryLock) 
     { 
      if (!ScriptCache.ContainsKey(edit)) 
      { 
       ScriptCache.Add(edit, host); 
      } 
     } 
    } 

    ... 
} 
+0

Merci! Cela a fonctionné parfaitement. Cela a agi comme si la classe entière était instanciée à chaque appel. Je me suis dit (si c'était le cas), même les objets statiques auraient été recréés. +1 ... merci pour l'aide! – Brosto