I have a Windows service which performs a fairly long running task. At the moment, I spawn a new thread, which executes a method which goes off and calls this windows service. This code looks like:
Thread thread = new Thread(new ThreadStart(ExecyuteLongRunningMethod));
thread.Start();
thread.Join();
Higher up in the callstack (when this code is done), a message box popups stating the result of the operation.
However, while this block of code executes (ExecuteLongRunningMethod calls the windows svc), a message box popups stating that nothing has changed as a result of the operation, but because this is before the code block above has completed, the wrong message box appears.
Thus, the question is, what would be the proper way to only continue execution in the winforms app (this is what calls the windows svc), ONLY when the windows service is finished? I am thinking that the approach above is incorrect as the thread will call the windows service (another process), so while the windows service does its stuff, my code (winforms app) will continue. Either some sort of signaling is required, or something like named pipes?
The app is in .NET 3.5.
Thanks
Expose the status of your service execution via a WCF API and call it using netTcp or named pipes, you could poll the service or use a WCF CallBack.
Why don't you use a BackgroundWorker, so you can set an event for its completion?
In Backgroundworker running method you can run the service and wait for a manual reset event (for example) or a mutex and, when received this you can exit main method.
So OnCompleted event is raised in your main thread (UI for example) and the job is done...
In your app add a Backgroundworker and name it bgw.
Then you can do:
private void bgw_DoWork(object sender, DoWorkEventArgs e)
{
// 1. Run the service
// 2. Wait for mutex
}
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Here you can handle the end of the service
// and return the status in main thread
}
Related
Hello I am make a long running service class that runs diffidently but it's thread is paused all the time except for once a day when it has to check some data for my asp.net website. It is a WCF file in an asp.net website. The class inherits from this interface :
[ServiceContract]
public interface IService
{
[OperationContract]
void DoWork();
}.
This is the code it uses for creating the thread the class run on :
//Initialize the thread
Thread = new Thread(new ThreadStart(threadDoSomething));
//The thread is a background thread; it is a long running service
Thread.IsBackground = true;
//This Thread does not need much CPU attention so it is not a high priority
Thread.Priority = ThreadPriority.Lowest;
//Run the tread
Thread.Start(this);
I have heard that IIS will occasionally stop long running processes to save memory, will it stop this process?
Yes, IIS will recycle ApplicationPools when no activity has been received in a period (it's configurable).
A simple trick to avoid this is to do that thread navigate a page on your web application to avoid it but it will finally sometime recycle it after a long period.
UPDATE:
Ehm... if your app is a windows service then IIS has nothing to do with your thread...
I am using the ApplicationPool class's ApplicationPool.Stop method to stop the app pool via C# code. This method stops the app pool, it is fine. But the issue is that I want to detect when the pool has stopped since that method takes some time to make the app pool in stopped state. Is there any event which I should wire to detect whether the app pool has stopped?
Edit: I can't use Global.asax (of site of which I am stopping the app pool) since I am stopping the app pool from another application.
You can SpinWait until your application pool is stopped. Something like this:
ApplicationPool pool = //your pool here.
pool.Stop();
if (SpinWait.SpinUntil(() => pool.State == ObjectState.Stopped, TimeSpan.FromSeconds(30)))
{
//The application pool has stopped
}
else
{
//The application pool did not stop within 30 seconds.
//An error probably occured.
}
You don't have to specify a timeout, however I would strongly recommend it. If you don't, you risk completely blocking the rest of your process.
My application is a asp.net web service. There is a one more windows service ruining in the same server and trigger the web-service by specified intervals.
So in each web-service call, in side the web server, it create a new thread and start to do the task that web service suppose to do.
Some times, this started thread could not finish the assigned task, before next web service call comes. So the next web-service call create a same kind of a new thread and assign new task to the new thread.
So if I check the server in busy situations, Sometime there are 20+ parallel threads ruining.
Every thing works fine. But server (windows 2003 sp2) looks not responding some times. So I check the CPU performance in the Task Manager and it shows 100% when the web-service start to work. even if there are only 1,2 threads same thing happens.
I feel something wrong. Am i doing something conceptually wrong. Appreciate some advice.
Edit
public class EmailPrinter : System.Web.Services.WebService
public void webServiceMethod()
{
Thread email_thread = new Thread(new ThreadStart(this.downloadEmails));
email_thread.Start();
}
private void downloadEmails(object sender, DoWorkEventArgs e)
{
EmailService.init();
EmailService.ReceiveEmail();
}
}
I have a C# Windows Service. The OnStart() method contains 3 lines that all they do is start a thread. The class itself has no static objects that would cause a delay. It is as simple as a service can be. My code is signed by a self made key.
Edit: I just figured out that assembly isn't signed, the rest are. It uses a few assemblies which are signed but the service itself isn't.
This code is running inside a virtual machine, whenever the host is running slow and this VM is booting up, the service will fail to start with this error:
A timeout was reached (30000 milliseconds) while waiting for the ServiceName service to connect.
Setting the service to delay start fixes it but it's a long delay and it's very annoying. Has anyone else had this problem with .NET services (2.0)?
The OnStart method:
protected override void OnStart(string[] args)
{
Thread startThread = new Thread(new ThreadStart(StartThread));
startThread.IsBackground = true;
startThread.Start();
}
The StartThread method, in which all I do is call another class so that the OnStart won't have to wait for static variable initialization or for the constructor method to end.
private void StartThread()
{
Worker mainThread = new Worker(this);
mainThread.RunWorker();
}
Thank you.
I think this is most likely due to the strong name signing that you have on your executable. In general, it's not good practice to do that on executables (see here). I have also experienced the same problem in one of my projects, where an executable took an incredible amount of time to start, and turned out it was due to strong name signing the executable (.NET 2.0 as well).
Consider turning AutoLog = false. I've seen where this flag can cause the timeout you're describing.
I have a console application that starts up, hosts a bunch of services (long-running startup), and then waits for clients to call into it. I have integration tests that start this console application and make "client" calls. How do I wait for the console application to complete its startup before making the client calls?
I want to avoid doing Thread.Sleep(int) because that's dependent on the startup time (which may change) and I waste time if the startup is faster.
Process.WaitForInputIdle works only on applications with a UI (and I confirmed that it does throw an exception in this case).
I'm open to awkward solutions like, have the console application write a temp file when it's ready.
One option would be to create a named EventWaitHandle. This creates a synchronization object that you can use across processes. Then you have your 'client' applications wait until the event is signalled before proceeding. Once the main console application has completed the startup it can signal the event.
http://msdn.microsoft.com/en-us/library/41acw8ct(VS.80).aspx
As an example, your "Server" console application might have the following. This is not compiled so it is just a starting point :)
using System.Threading;
static EventWaitHandle _startedEvent;
static void main()
{
_startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, #"Global\ConServerStarted");
DoLongRunnningInitialization();
// Signal the event so that all the waiting clients can proceed
_startedEvent.Set();
}
The clients would then be doing something like this
using System.Threading;
static void main()
{
EventWaitHandle startedEvent = new EventWaitHandle(false, EventResetMode.ManualReset, #"Global\ConServerStarted");
// Wait for the event to be signaled, if it is already signalled then this will fall throught immediately.
startedEvent.WaitOne();
// ... continue communicating with the server console app now ...
}
What about setting a mutex, and removing it once start up is done. Have the client app wait until it can grab the mutex before it starts doing things.
Include an is ready check in the app's client interface, or have it return a not ready error if called before it's ready.
Create a WCF service that you can use for querying the status of the server process. Only start this service if a particular command is passed on the command line. The following traits will ensure a very fast startup of this service:
Host this service as the first operation of the client application
Use the net.tcp or net.pipe binding because they start very quickly
Keep this service as simple as possible to ensure that as long as the console application doesn't terminate, it will remain available
The test runner can attempt to connect to this service. Retry the attempt if it fails until the console application terminates or a reasonably short timeout period expires. As long as the console application doesn't terminate unexpectedly you can rely on this service to provide any additional information before starting your tests in a reasonably short period of time.
Since the two(the console application, and integration test app that makes client calls - as I understand) are separate application, so there should be a mechanism - a bridge - that would tell play as a mediator(socket, external file, registry, etc).
Another possibility could be that you come up with an average time the console takes to load the services and use that time in your test app; well, just thinking out loud!