Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Preventing the "Stop" command on a Windows Service during a critical section of code. (C#/ASP.NET)

Posted on 2004-10-25
9
Medium Priority
?
455 Views
Last Modified: 2010-04-17
I have a Windows Service that I'm in the process of writing in C# using Visual Studio .NET. It is used to process credit card payments for Premium Members of our website. There is one part of the process which is really critical:

Once the user's details have been processed, resulting in the credit card being charged, it is important that the database is updated to set the user's billing date to one month in the future. If this does not happen, the card will be charged again an hour later, the next time the timer fires its "elapsed" event.

I have already got lots of try/catch blocks in my code and other flags I use to handle the situation where an exception occurs between these two lines of code. However, I realized that if someone stops the service during this critical section, the same problem could arise.

This leads to my question...

How can I ensure that my service does not stop until the important piece of code has finished executing?

This is fairly urgent so I would really appreciate any help that you could offer. It's my first Windows Service although I'm fairly familiar with C# and ASP.NET.
0
Comment
Question by:tacf
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 8

Accepted Solution

by:
AaronReams earned 1000 total points
ID: 12405084
Hi there,

You should enter/check your critical section in the OnStop() handler of your service.

/// <summary>
/// Stop this service.
/// </summary>
protected override void OnStop()
{
     // Need to enter critical section here to make sure everything is finished
}
0
 
LVL 7

Assisted Solution

by:jacobhoover
jacobhoover earned 1000 total points
ID: 12405692
Yes, a critical section should do it.  Have it locked by the thread that is charging then updating the DB and then unlocking it.  Then, on the OnStop function of the service, you need to try to acquire a lock on the same critical section.  This will protect the stop from occuring while in the middle of the process.  However, you may wish to impliment a more robust solution in which you would flag the account as an update in progress before you start incase your application (service) is killed via terminate process.  I would also then have a seperate table to log the CC transactions.

Just my 2 c.

Jake
0
 
LVL 8

Expert Comment

by:AaronReams
ID: 12405822
Also, keep this in mind.  If someone manually stops your service via the Services control panel applet, as long as you don't return from the OnStop() function (i.e. by blocking that thread and finishing up all your work in a separate thread), your service will actually continue to run indefinitely.  

However, one caveat, windows will display an error message saying your service didn't shut down in a timely fashion.  It displays this message after waiting ~ 2 minutes for OnStop to return.  
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 22

Expert Comment

by:cookre
ID: 12406526
If this weren't c#, I'd clear the SERVICE_ACCEPT_STOP flag in field dwControlsAccepted of the SERVICE_STATUS struct passed to the SetServiceStatus() API.  However, given that c# makes its own calls to SetServiceStatus() so you don't have to, I'd be surprised if your own clearing of the bit lasted very long.

But it may be worth a try to avoid the nasty messages in the event log.
0
 
LVL 19

Expert Comment

by:Fahad Mukhtar
ID: 12407453
try
this.CanStop = false;
while you are in the CS
0
 
LVL 1

Author Comment

by:tacf
ID: 12410555
I had already tried altering the value of CanStop and it results in an exception. The value of CanStop cannot be changed once the service has started.

As for logging the transactions, I am logging them in a log file in C:\Windows\System32\Logfiles rather than using the db for this.

How do I actually create a critical section in C#? I remember back in my University days studying mutual exclusion semaphores and all the rest but I don't know how to implement such a thing.
0
 
LVL 1

Author Comment

by:tacf
ID: 12410866
OK, I think I've got it.

In my OnStart() method I create a Mutex object called this.mutex.

At the start of my critical section of code, I have:

Mutex.WaitAny(new WaitHandle[] {this.mutex});

At the end of the critical section of code, I have:

this.mutex.ReleaseMutex();

In the OnStop() method, I have:

Mutex.WaitAny(new WaitHandle[] {this.mutex});

From testing with writing entries to the log file, I've discovered that this works properly. (I put in a 15 second delay in the middle of the critical section of code and when I stop the service, it waits until that part is finished.
0
 
LVL 1

Author Comment

by:tacf
ID: 12411058
I just realized I could use:

this.mutex.WaitOne();

instead of:

Mutex.WaitAny(new WaitHandle[] {this.mutex});

0
 
LVL 7

Expert Comment

by:jacobhoover
ID: 12550161
@tacf
  Any feedback/resolution/points distrobution?
0

Featured Post

Ask an Anonymous Question!

Don't feel intimidated by what you don't know. Ask your question anonymously. It's easy! Learn more and upgrade.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
We live in a world of interfaces like the one in the title picture. VBA also allows to use interfaces which offers a lot of possibilities. This article describes how to use interfaces in VBA and how to work around their bugs.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

610 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question