multi thread safety

C

CannonFodder

hi all, im new to c# and i think i may have coded myself into a bit of
a mess.

basically i am writing a windows service which audits all the pcs on a
network using WMI on a regular basis. The main processes are
performed in a Windows Service which scans Active Directory and for
each computer found it adds a process to the threadpool.

the process creates a new instance of a class which does the WMI
querying, this creates an XML file for each successfully scanned
machine.

one of the requirements for this project is to have this service
running, but when the host machine is logged on; to have a little
application which shows the status of the scanner, ie some info about
what machine (if any it is scanning), maybe a progress bar, that sort
of thing.

i know the windows service can't have its own UI, so i set up a remote
object class which has some public variables which are set in the
service, then i have a windows application which reads these public
variables.

this works fine for about a minute and then the application just
hangs.

This is the onStart code of the windows service, it registers the
remote object as a singleton and then creates a local reference to the
singleton to set parameters to it.

--------------------------------------------------------CODE
SAMPLE----------------------------------
protected override void OnStart(string[] args)
{
//register the singleton object on the tcpchannel
TcpChannel chan1 = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan1);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Singleton.singletonScannerStatus),
"ScannerStatus",
WellKnownObjectMode.Singleton);

Type oType = typeof(Singleton.singletonScannerStatus);
string strUri = "tcp://localhost:8085/ScannerStatus";

m_Obj = (Singleton.singletonScannerStatus)Activator.GetObject(oType,strUri);

.....
....
...
..
---------------------------------------------------------------------------------------------------------------

i've been looking into thread safety and believe this could
potentially be where my app is falling over, and i found references to
'double-checking' within the singleton class, so i added this code the
singleton class:
--------------------------------------------------------CODE
SAMPLE----------------------------------
private static singletonScannerStatus instance = null;

private int m_counter=0;
private string strStatus;
private static readonly object objPadlock = new object();


private singletonScannerStatus()
{
}

public static singletonScannerStatus Instance
{
get
{
if(instance ==null)
{
lock(objPadlock)
{
if(instance == null)
instance = new singletonScannerStatus();
}
}

return instance;
}
}
---------------------------------------------------------------------------------------------------------------
These are the 2 main methods of this class i am trying to use for my
appliaction. The windows service while its looping through the
computers and scanning them it calls "setStatus(string strNewStatus)"

and while this is happening i have a windows application which has a
timer and every second it calls "getStatus()" and puts the result into
a label object on a windows form.

--------------------------------------------------------CODE
SAMPLE----------------------------------

public void setStatus(string strNewStatus)
{
lock(objPadlock)
{
strStatus = strNewStatus;
}
}

public string getStatus()
{
lock(objPadlock)
{
return strStatus;
}
}
---------------------------------------------------------------------------------------------------------------

but the problem still exists, i've been racking my brain all day
trying to figure this one out and now have a head ache, any help is
much appreciated!

thanks in advance

Gavin
 
J

Jon Skeet [C# MVP]

This is the onStart code of the windows service, it registers the
remote object as a singleton and then creates a local reference to the
singleton to set parameters to it.

Double-checked locking doesn't work in .NET. See
http://www.pobox.com/~skeet/csharp/singleton.html

I think it's unlikely that this is your problem though.
but the problem still exists

Does it hang when you run it in a debugger? If so, what threads are
active, and where are they?

See http://www.pobox.com/~skeet/csharp/multithreading.html for multi-
threading information.
 
J

Jon Skeet [C# MVP]

Daniel Jin said:
correct me if I'm wrong, I seem to recall reading that although
double checked lock doesn't always work in .NET memory model, if run
on a x86 processor, the machine memory model guaranttees that it will
work.

Could be. I wouldn't be at all surprised. I just prefer to stick to
guaranteed things :)
 
S

Sunny

Hi,

Exposing a sigleton to remoting is better to be done that way (and you
do not have to use any singleton pattern after that):

protected override void OnStart(string[] args)
{
//register the tcpchannel
TcpChannel chan1 = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan1);

//create the instance you need to expose
m_Obj = new MySigleton();

//register for remoting
RemotingServices.Marshal(m_Obj, "ScannerStatus", typeof
(MySingleton);
......
}

Be sure, that you maintain the lifetime of your remoted object
correctly. For this situation it is betted to set it to null, and it
will live forever (until you stop the service).

Even if you are calling your singleton every second, and it should
prolong the lifetime, still I'd prefer to maintain it by myself.

Sunny


hi all, im new to c# and i think i may have coded myself into a bit of
a mess.

basically i am writing a windows service which audits all the pcs on a
network using WMI on a regular basis. The main processes are
performed in a Windows Service which scans Active Directory and for
each computer found it adds a process to the threadpool.

the process creates a new instance of a class which does the WMI
querying, this creates an XML file for each successfully scanned
machine.

one of the requirements for this project is to have this service
running, but when the host machine is logged on; to have a little
application which shows the status of the scanner, ie some info about
what machine (if any it is scanning), maybe a progress bar, that sort
of thing.

i know the windows service can't have its own UI, so i set up a remote
object class which has some public variables which are set in the
service, then i have a windows application which reads these public
variables.

this works fine for about a minute and then the application just
hangs.

This is the onStart code of the windows service, it registers the
remote object as a singleton and then creates a local reference to the
singleton to set parameters to it.

--------------------------------------------------------CODE
SAMPLE----------------------------------
protected override void OnStart(string[] args)
{
//register the singleton object on the tcpchannel
TcpChannel chan1 = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan1);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Singleton.singletonScannerStatus),
"ScannerStatus",
WellKnownObjectMode.Singleton);

Type oType = typeof(Singleton.singletonScannerStatus);
string strUri = "tcp://localhost:8085/ScannerStatus";

m_Obj = (Singleton.singletonScannerStatus)Activator.GetObject(oType,strUri);

....
...
..
.
---------------------------------------------------------------------------------------------------------------

i've been looking into thread safety and believe this could
potentially be where my app is falling over, and i found references to
'double-checking' within the singleton class, so i added this code the
singleton class:
--------------------------------------------------------CODE
SAMPLE----------------------------------
private static singletonScannerStatus instance = null;

private int m_counter=0;
private string strStatus;
private static readonly object objPadlock = new object();


private singletonScannerStatus()
{
}

public static singletonScannerStatus Instance
{
get
{
if(instance ==null)
{
lock(objPadlock)
{
if(instance == null)
instance = new singletonScannerStatus();
}
}

return instance;
}
}
---------------------------------------------------------------------------------------------------------------
These are the 2 main methods of this class i am trying to use for my
appliaction. The windows service while its looping through the
computers and scanning them it calls "setStatus(string strNewStatus)"

and while this is happening i have a windows application which has a
timer and every second it calls "getStatus()" and puts the result into
a label object on a windows form.

--------------------------------------------------------CODE
SAMPLE----------------------------------

public void setStatus(string strNewStatus)
{
lock(objPadlock)
{
strStatus = strNewStatus;
}
}

public string getStatus()
{
lock(objPadlock)
{
return strStatus;
}
}
---------------------------------------------------------------------------------------------------------------

but the problem still exists, i've been racking my brain all day
trying to figure this one out and now have a head ache, any help is
much appreciated!

thanks in advance

Gavin
 
C

CannonFodder

cheers for the speedy response guys, much appreciated.

Jon: i tried all thread safety methods on that skeet site, but they
all had the same effect (the app hanging after a minute or so).

sunny: it worked! i registered my singleton object in the way you
mentioned in your reply and it doesnt hang, i'm definately gonna look
up

"RemotingServices.Marshal(m_Obj, "ScannerStatus",
typeof(MySingleton);"

to see why its different from "RegisterWellKnownServiceType".

thanks again :)


Sunny said:
Hi,

Exposing a sigleton to remoting is better to be done that way (and you
do not have to use any singleton pattern after that):

protected override void OnStart(string[] args)
{
//register the tcpchannel
TcpChannel chan1 = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan1);

//create the instance you need to expose
m_Obj = new MySigleton();

//register for remoting
RemotingServices.Marshal(m_Obj, "ScannerStatus", typeof
(MySingleton);
.....
}

Be sure, that you maintain the lifetime of your remoted object
correctly. For this situation it is betted to set it to null, and it
will live forever (until you stop the service).

Even if you are calling your singleton every second, and it should
prolong the lifetime, still I'd prefer to maintain it by myself.

Sunny


hi all, im new to c# and i think i may have coded myself into a bit of
a mess.

basically i am writing a windows service which audits all the pcs on a
network using WMI on a regular basis. The main processes are
performed in a Windows Service which scans Active Directory and for
each computer found it adds a process to the threadpool.

the process creates a new instance of a class which does the WMI
querying, this creates an XML file for each successfully scanned
machine.

one of the requirements for this project is to have this service
running, but when the host machine is logged on; to have a little
application which shows the status of the scanner, ie some info about
what machine (if any it is scanning), maybe a progress bar, that sort
of thing.

i know the windows service can't have its own UI, so i set up a remote
object class which has some public variables which are set in the
service, then i have a windows application which reads these public
variables.

this works fine for about a minute and then the application just
hangs.

This is the onStart code of the windows service, it registers the
remote object as a singleton and then creates a local reference to the
singleton to set parameters to it.

--------------------------------------------------------CODE
SAMPLE----------------------------------
protected override void OnStart(string[] args)
{
//register the singleton object on the tcpchannel
TcpChannel chan1 = new TcpChannel(8085);
ChannelServices.RegisterChannel(chan1);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(Singleton.singletonScannerStatus),
"ScannerStatus",
WellKnownObjectMode.Singleton);

Type oType = typeof(Singleton.singletonScannerStatus);
string strUri = "tcp://localhost:8085/ScannerStatus";

m_Obj = (Singleton.singletonScannerStatus)Activator.GetObject(oType,strUri);

....
...
..
.
---------------------------------------------------------------------------------------------------------------

i've been looking into thread safety and believe this could
potentially be where my app is falling over, and i found references to
'double-checking' within the singleton class, so i added this code the
singleton class:
--------------------------------------------------------CODE
SAMPLE----------------------------------
private static singletonScannerStatus instance = null;

private int m_counter=0;
private string strStatus;
private static readonly object objPadlock = new object();


private singletonScannerStatus()
{
}

public static singletonScannerStatus Instance
{
get
{
if(instance ==null)
{
lock(objPadlock)
{
if(instance == null)
instance = new singletonScannerStatus();
}
}

return instance;
}
}
---------------------------------------------------------------------------------------------------------------
These are the 2 main methods of this class i am trying to use for my
appliaction. The windows service while its looping through the
computers and scanning them it calls "setStatus(string strNewStatus)"

and while this is happening i have a windows application which has a
timer and every second it calls "getStatus()" and puts the result into
a label object on a windows form.

--------------------------------------------------------CODE
SAMPLE----------------------------------

public void setStatus(string strNewStatus)
{
lock(objPadlock)
{
strStatus = strNewStatus;
}
}

public string getStatus()
{
lock(objPadlock)
{
return strStatus;
}
}
---------------------------------------------------------------------------------------------------------------

but the problem still exists, i've been racking my brain all day
trying to figure this one out and now have a head ache, any help is
much appreciated!

thanks in advance

Gavin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top