Service (with Thread) Don't Stop

  • Thread starter Thread starter Zahi S
  • Start date Start date
Z

Zahi S

Hi,
Here is my service class, It simply don't stop when i remove the tread
everything is OK:

using System;
using System.Threading;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Xml;
using System.IO;

namespace MzDirMove
{
public class MzDirMove : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
ThreadStart otter;
Thread oThread;
private XmlDocument xDoc;
private bool tloop=true;


public MzDirMove()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();

// TODO: Add any initialization after the InitComponent call
}

// The main entry point for the process
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;

// More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
//
// ServicesToRun = New System.ServiceProcess.ServiceBase[] {new
Service1(), new MySecondUserService()};
//
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new
MzDirMove() };

System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// MzDirMove
//
this.CanHandlePowerEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.ServiceName = "MzDirMove";

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Set things in motion so your service can do its work.
/// </summary>
protected override void OnStart(string[] args)
{
EventLog.WriteEntry("MzDirMove","MzDirMove
starting",EventLogEntryType.Information,4000);
xDoc=new XmlDocument();
xDoc.Load("C:\\work\\mzDirMoveZ\\mzdirmove.xml");
otter = new ThreadStart(Route);
Thread oThread = new Thread(otter);
oThread.Start();
EventLog.WriteEntry("MzDirMove","MzDirMove starting
2",EventLogEntryType.Information,4000);

}

/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
tloop=false;
// Time should be longer than Run() loop takes to execute.
Thread.Sleep(10000);
// If the thread hasn't exited on its own by now,
// Kill it.
if (oThread.IsAlive) oThread.Abort();

oThread = (System.Threading.Thread) null;
}
public void Route()
{

while (tloop)
{
Thread.Sleep(1000);
// Do the rest here
}
}
}
}
 
Zahi S said:
Here is my service class, It simply don't stop when i remove the tread
everything is OK:

<snip>

For one thing, there's no guarantee that the change to tstop is going
to be noticed in the other thread. You need to synchronize both write
and read access to it in order to guarantee that the change is visible.

If that doesn't help, please write a short but complete example which
doesn't do anything other than what's needed to demonstrate the
problem.
 
Hi Jon/Zahi,

Might also consider whether the thread should be set to be a background
thread. Then when the main thread exits, it will do so automatically too.

HTH,
 
Hi Jon,
The lock statement didn't help,
I'm attaching my code (Cleaned up, only the problematic sections)
Many Thanks
Zahi


using System;
using System.Threading;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Xml;
using System.IO;

namespace MzDirMove
{
public class MzDirMove : System.ServiceProcess.ServiceBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
ThreadStart otter;
Thread oThread;
private bool tloop=true;


public MzDirMove()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();

// TODO: Add any initialization after the InitComponent call
}

// The main entry point for the process
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;

ServicesToRun = new System.ServiceProcess.ServiceBase[] { new
MzDirMove() };

System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// MzDirMove
//
this.CanHandlePowerEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.ServiceName = "MzDirMove";

}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

/// <summary>
/// Set things in motion so your service can do its work.
/// </summary>
protected override void OnStart(string[] args)
{
otter = new ThreadStart(Route);
Thread oThread = new Thread(otter);
oThread.Start();

}

/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
lock(this)
tloop=false;
// Time should be longer than Run() loop takes to execute.
Thread.Sleep(10000);
// If the thread hasn't exited on its own by now,
// Kill it.
if (oThread.IsAlive) oThread.Abort();

oThread = (System.Threading.Thread) null;
}
public void Route()
{
bool jtloop;
lock(this)
jtloop=tloop;

while (jtloop)
{
Thread.Sleep(1000);
// Do the rest here
lock(this)
jtloop=tloop;
}
}
}
}
 
How Do I Do it ?

Zahi

Greg Low (MVP) said:
Hi Jon/Zahi,

Might also consider whether the thread should be set to be a background
thread. Then when the main thread exits, it will do so automatically too.

HTH,
 
Zahi S said:
The lock statement didn't help,
I'm attaching my code (Cleaned up, only the problematic sections)

<snip>

Right - I'll have a closer look at it later.
 
Zahi S said:
The lock statement didn't help,
I'm attaching my code (Cleaned up, only the problematic sections)

Okay, I've got it: in OnStart, you're declaring a new local variable
called oThread, which means that the *instance* variable oThread is
never written to - so OnStop actually throws a NullReferenceException,
so never completes. It's a shame that the exception isn't noted
anywhere - but you can reproduce it by taking out the extra threading
entirely, getting rid of everything from OnStart and just making OnStop
throw an exception.
 
Back
Top