2009-07-08 6 views
0

J'utilise un System.Threading.ThreadPool pour gérer une file d'attente de travaux à partir d'un service. Je l'ai déjà mis en œuvre l'exploitation forestière comme ça ...Puis-je appeler des méthodes statiques sur une instance de classe statique à partir d'un thread de travail?

abstract class Global 
{ 
    public static LogFile LogFile = null; 
} 

public class LogFile : IDisposable 
{ 
    private StreamWriter sw; 
    public LogFile(string path){} 
    public void WriteEntry(string logText) 
    { 
     lock (sw) 
     { 
      sw.WriteLine(logText); 
     } 
    } 
} 

Je veux créer le journal au démarrage du service et de l'utiliser de mes threads de travail .. quelque chose comme la file d'attente ... ce

//On Service Start 
Global.LogFile = new LogFile("log.txt"); 

//Kick of worker thread 
ThreadPool.QueueUserWorkItem(objWrkrThread.CallbackMethod, iCount); 

//Worker thread logs an entry in CallbackMethod() 
Global.LogFile.WriteEntry("Hello World"); 

Est ce coffre-fort? L'appel d'une méthode sur une instance statique d'une classe va-t-elle par inadvertance «synchroniser» ou «bloquer» mes threads?

Michael

+0

Les méthodes statiques ne sont pas intrinsèquement sûres. S'il vous plaît voir cette réponse par Jon Skeet [http://stackoverflow.com/questions/1090650/are-static-methods-thread-safe/1090670#1090670] – TheVillageIdiot

Répondre

3

Rien ne «synchronisera» ou «bloquera» à moins d'écrire du code dans votre méthode. Peu importe qu'il s'agisse d'une méthode d'instance ou d'une méthode statique. Par conséquent, par défaut, WriteEntry ne bloquera aucun appel de vos threads mais il pourrait très bien corrompre le fichier si vous n'écrivez pas le code pour gérer plusieurs appels simultanés.

En savoir plus sur ce sujet ici:

Are static methods thread safe

0

Ce n'est pas sûr d'avoir plusieurs threads appellent WriteEntry en même temps à moins qu'il a été conçu pour être en sécurité.

+0

Il s'avère que l'exemple de Scotty de la façon de faire des singletons sous .NET est trop compliqué. Au lieu de cela, vous pouvez éviter le verrouillage explicite en écrivant quelque chose comme: privé static Log _instance = nouveau Log (_path) –

0

Ce que vous essayez de faire des sons comme le candidat parfait pour une classe Singleton. Je sais que c'est un mauvais film, mais parfois la simplicité en vaut la peine.

Vous pouvez créer une classe de journal comme celle-ci et vous devriez être sûr pour les threads.

public sealed class Log 
{ 
    static Log instance=null; 
    static readonly object lockObject = new object(); 
    static string path = "log.txt"; 

    Log() 
    { 
    } 

    public static Log Instance 
    { 
     get 
     { 
      lock (lockObject) 
      { 
       if (instance==null) 
       { 
        instance = new Log(); 
       } 
       return instance; 
      } 
     } 
    } 

    public void WriteLine(string message) 
    { 
     lock(lockObject) 
     { 
      using(StreamWriter sw = new StreamWriter(File.Open(path, FileMode.Append))) 
      { 
      sw.WriteLine(message); 
      } 
     } 
    } 
} 

Ensuite, dans votre code, vous appelez simplement comme ceci:

Log executionLog = Log.Instance; 
executionLog.WriteLine("this is a log message."); 

Vous pouvez également gérer l'ouverture du fichier en fil similaire des méthodes sûres pour se débarrasser de la tête sur l'ouverture et la fermeture de la déposer chaque écriture.

+0

idée intéressante, merci d'avoir pris le temps de sortir le code scotty. –

+0

Etes-vous sûr que le code ci-dessus va compiler? lock est un mot-clé et vous ne pouvez pas l'utiliser comme nom de votre objet. – SolutionYogi

+0

@SolutionYogi, vous avez raison. Je l'ai juste tapé, pas de test. J'ai mis à jour ma réponse. – scottm

Questions connexes