none
Verständnisfrage zu Threads innerhalb eines Dienstes RRS feed

  • Frage

  • Hallo zusammen,

      innerhalb eines Dienstes habe ich einen TcpListener-Thread und einen Timer, Quellcode-Auszug siehe unten. Die eigentliche "Logik" steckt in der Klasse "MyClass". Frage: Was muss ich beachten, um Thread-Sicher zu programmieren, außer dass Variablen, auf die Thread-Übergreifend zugegriffen wird, als "volatile" deklariert werden müssen?

     

     

      public partial class svcServiceBase : ServiceBase
      {
    
        private Thread tTcpListener;
        private System.Timers.Timer tiMain;
    
    private volatile MyClass MeineKlasse; private volatile Boolean ThreadTcpListenerBeenden = false; private volatile Boolean AktionLaeuft = false; public svcServiceBase() { InitializeComponent(); } protected override void OnStart(string[] args) { MeineKlasse = new MyClass(); tiMain = new System.Timers.Timer(); tiMain.Elapsed += new ElapsedEventHandler(tiMain_Elapsed); tiMain.Interval = 3 * 60 * 1000; tiMain.Enabled = true; tTcpListener = new Thread(ThreadTcpListener); tTcpListener.Start(); } protected override void OnStop() { ThreadTcpListenerBeenden = true; tTcpListener.Join(); tiMain.Enabled = false; } private void tiMain_Elapsed(object source, ElapsedEventArgs e) { AktionLaeuft = true; MeineKlasse.StatusUeberpruefen(); AktionLaeuft = false; } private void ThreadTcpListener() { TcpListener iTcpListener = new TcpListener(IPAddress.Any, 8080); iTcpListener.Start(); while (!ThreadTcpListenerBeenden) { while (!iTcpListener.Pending() && !ThreadTcpListenerBeenden) Thread.Sleep(100); if (!ThreadTcpListenerBeenden) ThreadPool.QueueUserWorkItem(new WaitCallback(VerbindungAbarbeiten), iTcpListener.AcceptTcpClient()); } iTcpListener.Stop(); } private void VerbindungAbarbeiten(object neu_TcpClient) { Byte[] byDaten = new Byte[1024]; Int32 intBytesGelesen = 0; String stKommando = ""; String stReturn = ""; TcpClient iTcpClient = (TcpClient)neu_TcpClient; NetworkStream iNetworkStream = iTcpClient.GetStream(); intBytesGelesen = iNetworkStream.Read(byDaten, 0, byDaten.Length); stKommando = Encoding.Default.GetString(byDaten); if (stKommando.ToLower().StartsWith("diesisteintest")) {
      while (AktionLaeuft)
    Thread.Sleep(10);
       MeineKlasse.DoWork(); } else if (stKommando.ToLower().StartsWith("nocheintest")) { MeineKlasse.DoWork2(); } iNetworkStream.Close(); iTcpClient.Close(); } }

    Gruß,

     

    Matthias


    Donnerstag, 20. Oktober 2011 09:02

Antworten

  • Hallo zusammen,

      scheinbar funktioniert das "einfach so", bei meinen Tests sind keinerlei Probleme aufgetreten, manches ist ja einfacher als man zunächst vermutet. Wenn man von Threads aus auf GUI-Objekte zugreift, verwendet man ja "Invoke", das hab' ich verstanden, aber in einem Service hat man ja keine GUI.

      Also beachte ich das "volatile" - und wenn Thread-übergreifend Variablen geändert werden, baue ich eine Verriegelung ein - z.B. über eine Variable "AktionLaeuft" -, dann sollte es klappen.

    Gruß,

    Matthias
    Freitag, 21. Oktober 2011 15:51