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