2009-07-08 3 views
0

Ich verwende ein System.Threading.ThreadPool, um eine Warteschlange von Jobs von einem Dienst zu verwalten. Ich habe bereits umgesetzt wie diese Anmeldung ...Kann ich statische Methoden für eine statische Klasseninstanz von einem Worker-Thread aufrufen?

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

ich das Protokoll bei Dienststart erstellen möchten, und verwenden Sie es aus meiner Warteschlange Worker-Threads .. so etwas wie dieses ...

//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"); 

Ist das sicher? Wird das Aufrufen einer Methode für eine statische Instanz einer Klasse versehentlich meine Threads "synchronisieren" oder "blockieren"?

Michael

+0

Die statischen Methoden sind nicht von Natur aus threadsicher. Bitte sehen Sie diese Antwort von Jon Skeet [http://stackoverflow.com/questions/1090650/are-static-methods-thread-safe/1090670#1090670] – TheVillageIdiot

Antwort

3

Nichts wird 'synchronisieren' oder 'blockieren', es sei denn, Sie schreiben Code in Ihre Methode. Es spielt keine Rolle, ob es sich um eine Instanzmethode oder eine statische Methode handelt.

Standardmäßig wird WriteEntry keine Aufrufe von Ihren Threads blockieren, aber es könnte sehr gut Datei beschädigen, wenn Sie nicht den Code für mehrere gleichzeitige Aufrufe schreiben.

Lesen Sie mehr zu diesem Thema hier:

Are static methods thread safe

0

Es ist nicht sicher mehrere Threads nennen Writeentry zur gleichen Zeit haben, es sei denn, es wurde entwickelt, um sicher zu sein.

+0

Es stellt sich heraus, dass Scotty Beispiel für Singletons unter .NET ist zu kompliziert. Stattdessen können Sie das explizite Sperren vermeiden, indem Sie einfach Folgendes schreiben: private static Log _instance = new Log (_path) –

0

Was Sie versuchen, für eine Singleton-Klasse klingt wie der perfekte Kandidat zu tun. Ich weiß, dass es einen schlechten Wickel bekommt, aber manchmal ist es die Einfachheit wert.

Sie können eine Protokollklasse wie diese erstellen und Sie sollten threadsicher sein.

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

Dann in Ihrem Code, rufen Sie es einfach so:

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

Sie können die Datei auch in ähnlichen Thread sichere Methoden verwalten Öffnen des über Kopf der Öffnung, um loszuwerden, und Schließen der Datei jeden Schreibvorgang.

+0

interessante Idee, danke, dass Sie sich die Zeit genommen haben, den Code scotty auszumachen. –

+0

Sind Sie sicher, dass der obige Code kompiliert wird? Sperre ist ein Schlüsselwort und Sie können es nicht als den Namen Ihres Objekts verwenden. – SolutionYogi

+0

@SolutionYogi, Sie haben Recht. Ich tippte es einfach aus, keine Tests. Ich habe meine Antwort aktualisiert. – scottm