i am developing a WCF application that does not adhere to the idea world of a true SOA in that it will have a few basic calls.
1) Start Process
2) Check if process is still running
3) Get results
This is all fine, but in order for execution to return from the 'start process' I am running my code in a separate thread using
oThread = new Thread(new ThreadStart(wbrt.Calculate));
The problem is it has been known (though rare) for the COM call to hog and sit at 50~100% cpu and consume lots of memory. There is nothing I can do to prevent this.
What I want to do is have a watchdog thread that will kill off the COM call if it is still running after some time (say 5 minutes).
Is there a best practice here? I have been reading the following blog:
http://weblogs.asp.net/israelio/archive/2004/06/19/159985.aspx
in which he makes use of 'AutoResetEvent' and 'WaitOne' problem here is WaitOne is blocking so I'd have to have a thread within a thread.
Could I use a simple Thread Timer here? I saw that the timer will execute even if the thread has closed (i.e. finished ok) is that a problem if I use a flag or something to stop use of now dead objects?
Also I am creating my COM object using Activator.CreateInstance I tried Aborting the thread, but it does not kill the COM object and I have since read that Abort is bad.
My solution is to get the PID of the COM instance and simply kill, working on the assumption that if the timeout has hit diplomacy with the thread has gone out of the window.
Any thoughts well received!
Easiest way to do this is one ManualResetEvent with calling WaitAny() with a timeout value.
ManualResetEvent _evtActor = new ManualResetEvent();
public void Start()
{
this._evtActor.Reset();
ThreadPool.QueueUserWorkItem(new WaitCallback(DoStuff));
int result = ManualResetEvent.WaitAny(
new WaitHandle[] { this._evtActor },
30 * 1000); // Wait 30sec
if (result == ManualResetEvent.WaitTimeout)
{
Console.WriteLine("Timeout occurred!");
}
else
{
Console.WriteLine("Done!");
}
}
public void DoStuff()
{
Console.WriteLine("Doing stuff.");
Thread.Sleep(45 * 1000); // sleep for 45sec;
this._evtActor.Set();
}
Related
I have a WinForms application on .NET 3.5. In this form, the user triggers an operation which is executed in another thread (a BackgroundWorker to be precise) so as to not block the UI thread. I'm in MVP, so all this is being done by a presenter which interacts with an interface to the view (implemented by the Windows Form). So far so good.
I would like to introduce functionality whereby a timeout period is introduced for the background operation to complete before cancelling it. Sounds simple enough. But the background operation calls a single function on a third-party component which may never return, so the cancellation capabilities of the BackgroundWorker are of no use to me here. Also, the BackgroundWorker.RunWorkerCompleted allowed me to get back on the UI thread, so I need to wait for the timeout or success and be able to get back to my calling thread (namely the UI thread).
I tried this using a plain old Thread (which does support Abort()) and a Timer running on a second thread, but can't seem to get it to work quite right since Join() is blocking my UI thread despite the description stating that it will block "while continuing to perform standard COM and SendMessage pumping". Admittedly I assumed this implied that it would continue to process Windows Messages, which was not the case.
int timeoutInMsec = 10000;
Thread connectThread = new Thread(Connect);
Thread timerThread = new Thread(() =>
{
var timer = new System.Windows.Forms.Timer() { Interval = timeoutInMsec };
timer.Tick += (_s, _e) =>
{
timer.Stop();
if (connectThread.ThreadState == ThreadState.Running)
connectThread.Abort();
};
};
connectThread.Start();
timerThread.Start();
timerThread.Join();
connectThread.Join();
Based on this question, I tried removing the second timer thread and adding a ManualResetEvent and calling Set() when the timer ticked, or when the Connect method did indeed complete. Here, instead of Join I used WaitOne, but unfortunately this also blocks my UI thread. I also found this other question, which a CancellationTokenSource which unfortunately is not available in .NET 3.5.
So, how can I spin my worker up and be able to terminate it after a given amount of time in .NET 3.5, while at the same time be able to get back to the thread where I spun up the worker thread to execute a sort of OnCompleted handler?
Many thanks in advance!
PS: I don't have a lot of experience in multi-threaded programming in .NET, so I'm sorry if this is trivial.
If I understood your question correctly, the following algorithm should solve your problem:
As before, create a BackgroundWorker to do your background work.
In BackgroundWorker_DoWork,
create a new thread (let's call it the "third-party thread") to call your third-party library, and then
wait for the third-party thread to finish or the timeout to elapse. (*)
That way, your UI won't block, since only the Backgroundworker thread is waiting, not the main thread.
Now about the interesting part: How do you wait for the third-party thread to finish (the step marked with (*))?
My suggestion would be to simply use "loop waiting with sleep", i.e. (pseudo-code, you can use the Stopwatch class for the timeout):
do until (third-party thread has finished or x seconds have elapsed):
Thread.Sleep for 100ms
if third-party thread has not finished:
Abort it // we don't have another choice
else
Process the result
It's not best practice, but it's simple, it gets the job done and you can always replace it with fancy cross-thread-syncronization stuff (which is non-trivial to get right) once you got it all working.
It's useless to create a Forms.Timer on a non-gui thread. Don't create it on a separate thread. Why are you Joining the threads? The usage of Join is to block the current thread until the other thread is finished.
This is untested pseudo code, this is for example purpose.
public class Form1: Form1
{
private int timeoutInMsec = 10000;
private System.Windows.Forms.Timer _timer;
private Thread _connectThread;
public Form1()
{
_connectThread = new Thread(Connect);
_connectThread.Start();
_timer = new System.Windows.Forms.Timer() { Interval = timeoutInMsec };
_timer.Tick += (_s, _e) =>
{
_timer.Stop();
if (_connectThread.ThreadState == ThreadState.Running)
_connectThread.Abort();
};
};
}
private void Connected()
{
}
private void Aborted()
{
}
private void Connect()
{
try
{
DoConnect3rdPartyStuff();
this.Invoke(Connected);
}
catch(ThreadAbortException)
{
// aborted
this.Invoke(Aborted);
}
}
}
I have a console app that runs some on demand reporting in a webapplication. The app starts, runs some housecleaning, starts a (1 second) timer, and blocks on a Console.ReadLine(); statement. (I've been meaning to stuff it into a service instead, but that's for another day)
Right now this has no exception-handling, so if the sql server it polls against goes down or there is a network hiccup, it just crashes. I'm trying to implement a crude exception-handling now. Inside the timer-callback I have stuffed the sql-query inside a trycatch. If it fails, it handles the exception by logging, increasing a failurecounter and resuming the timer. If it fails more than 5 times I want it to exit the app (sort of) gracefully. How can I force-quit a console app that is blocked with a readline statement?
Code in a gist: https://gist.github.com/cwattengard/11171563
I think a more elegant solution is to block with a reset event. The timer callback sets this at some point when it considers that it no longer has work to do.
static readonly ManualResetEvent reset = new ManualResetEvent(false);
static void Main(string[] args)
{
var t = new Timer(TimerCallback, null, -1, 1000);
t.Change(0, 1000);
reset.WaitOne(); // the application will sit here until the timer tells it to continue.
}
private static void TimerCallback(object state)
{
try
{
// do stuff.
}
catch (Exception e)
{
failureCounter++;
if (failureCounter > 5)
{
reset.Set(); // release the reset event and the application will exit,
return;
}
}
}
The best way would be to use some sort of signalling mechanism.
For example you start the main thread, do all your initialization (timer etc) then create a non signaled ManualResetEvent and wait on it to fire. If the callback from the timer decides the application should terminate it signals the ManualResetEvent and the main thread is released, completes, and terminates the program...
As a matter of general approach, you should always use signaling and ""cooperative multi-tasking"" within your application. In the sense you signal other threads\ tasks\ actors\ whatever to do stuff, you shouldn't forcefully kill them...
I actually develop a Windows service in VS 2012 / .NET 4.5.
The service is following the scheme of the code snippet below:
Using a timer
Executes some desired operation every couple of minutes.
The process takes about 10 minutes to complete
I use a single thread in the service
What I am worried about is that if somebody stops the service via the management console, it might be just during the process that the service is doing.
I have done some reading about stopping Windows service with request stop, but am a bit lost. Sometimes WorkerThreads are created, sometimes ManualResetEvents are created, but up to now I couldn't fully grasp the best way forward for my Windows service.
I need to wait until the processing is properly finished in the onStop method before stopping the Windows service.
What is the best way forward then, also considering the code snippet below?
Thanks all!
namespace ImportationCV
{
public partial class ImportationCV : ServiceBase
{
private System.Timers.Timer _oTimer;
public ImportationCV()
{
InitializeComponent();
if (!EventLog.SourceExists(DAL.Utilities.Constants.LOG_JOURNAL))
{
EventLog.CreateEventSource(DAL.Utilities.Constants.LOG_JOURNAL, DAL.Utilities.Constants.SOURCE_JOURNAL);
}
EventLog.Source = DAL.Utilities.Constants.SOURCE_JOURNAL;
EventLog.Log = DAL.Utilities.Constants.LOG_JOURNAL;
}
protected override void OnStart(string[] args)
{
int intDelai = Properties.Settings.Default.WatchDelay * 1000;
_oTimer = new System.Timers.Timer(intDelai);
_oTimer.Elapsed += new ElapsedEventHandler(this.Execute);
_oTimer.Start();
EventLog.WriteEntry(DAL.Utilities.Constants.LOG_JOURNAL, "Service " + DAL.Utilities.Constants.SERVICE_TITLE + " started at " + DateTime.Now.ToString("HH:mm:ss"), EventLogEntryType.Information);
}
protected override void OnStop()
{
if (_oTimer != null && _oTimer.Enabled)
{
_oTimer.Stop();
_oTimer.Dispose();
}
EventLog.WriteEntry(DAL.Utilities.Constants.LOG_JOURNAL, "Service " + DAL.Utilities.Constants.SERVICE_TITLE + " stopped at " + DateTime.Now.ToString("HH:mm:ss"), EventLogEntryType.Information);
}
private void Execute(object source, ElapsedEventArgs e)
{
_oTimer.Stop();
try
{
//Process
}
catch (Exception ex)
{
EventLog.WriteEntry(DAL.Utilities.Constants.LOG_JOURNAL, (ex.StackTrace + ("\r\n" + ex.Message)), EventLogEntryType.Error);
}
_oTimer.Start();
}
}
}
As a test case, I put a call to System.Threading.Thread.Sleep(500000) in the OnStop() callback of my Windows service. I started the service and then stopped it. I got the window with the progress bar indicating that the Service Control Manager (SCM) was attempting to stop the service. After about 2 minutes, I got this response from the SCM:
After I dismissed this window, the status of my service in the SCM changed to Stopping, and I noticed that the service continued to run in Task Manager. After the sleep elapsed (nearly 6 minutes later), the process stopped. Refreshing the SCM window showed the service was no longer running.
I take a couple of things away from this. First, OnStop() should really attempt to stop the service in a timely manner just as part of playing nice with the system. Second, depending on how your OnStop() method is structured, you could force the service to ignore a preemptive request to stop, instead stopping when you say so. This is not recommended, but it appears that you could do this.
As to your particular situation, the thing you have to understand is that the System.Timers.Timer.Elapsed event fires on a ThreadPool thread. By definition, this is a background thread, which means that it will not keep the application running. When the service is told to shut down, the system will stop all background threads and then exit the process. So your concern about keeping the processing going until it is finished despite being told by the SCM to shutdown cannot occur the way you've got things structured currently. To do that, you'd need to create a formal System.Threading.Thread object, set it as a foreground thread, and then use the timer to trigger this thread to execute (as opposed to being done in the Elapsed callback).
All of that said, I still think you'll want to play nicely with the system, which means timely shutdown of the service when requested to do so. What happens if, for example, you need to reboot the machine? I haven't tested it, but if you force your service to continue running until the processing is complete, the system may indeed wait until the process finishes before actually restarting. That's not what I would want from my service.
So I would suggest one of two things. The first option would be to break the processing into distinct chunks that can be done individually. As each chunk is finished, check to see if the service is stopping. If so, exit the thread gracefully. If this cannot be done, then I would introduce something akin to transactions to your processing. Let's say that you're needing to interact with a bunch of database tables and interrupting the flow once it's started becomes problematic because the database may be left in a bad state. If the database system allows transactions, this becomes relatively easy. If not, then do all the processing you can in memory and commit the changes at the last second. That way, you only block shutting down while the changes are being committed as opposed to blocking for the entire duration. And for what it's worth, I do prefer using ManualResetEvent for communicating shutdown commands to threads.
To avoid rambling any further, I'll cut it off here. HTH.
EDIT:
This is off the cuff, so I won't verify its accuracy. I'll fix any problem you (or others) may find.
Define two ManualResetEvent objects, one for shutdown notification and one for processing notification, and the Thread object. Change the OnStart() callback to this:
using System.Threading;
using Timer = System.Timers.Timer; // both Threading and Timers have a timer class
ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
ManualResetEvent _processEvent = new ManualResetEvent(false);
Thread _thread;
Timer _oTimer;
protected override void OnStart(string[] args)
{
// Create the formal, foreground thread.
_thread = new Thread(Execute);
_thread.IsBackground = false; // set to foreground thread
_thread.Start();
// Start the timer. Notice the lambda expression for setting the
// process event when the timer elapses.
int intDelai = Properties.Settings.Default.WatchDelay * 1000;
_oTimer = new Timer(intDelai);
_oTimer.AutoReset = false;
_oTimer.Elapsed += (sender, e) => _processEvent.Set();
_oTimer.Start();
}
Change your Execute() callback to something like this:
private void Execute()
{
var handles = new WaitHandle[] { _shutdownEvent, _processEvent };
while (true)
{
switch (WaitHandle.WaitAny(handles))
{
case 0: // Shutdown Event
return; // end the thread
case 1: // Process Event
Process();
_processEvent.Reset(); // reset for next time
_oTimer.Start(); // trigger timer again
break;
}
}
}
Create the Process() method like this:
private void Process()
{
try
{
// Do your processing here. If this takes a long time, you might
// want to periodically check the shutdown event to see if you need
// exit early.
}
catch (Exception ex)
{
// Do your logging here...
// You *could * also shutdown the thread here, but this will not
// stop the service.
_shutdownEvent.Set();
}
}
Finally, in the OnStop() callback, trigger the thread to shutdown:
protected override void OnStop()
{
_oTimer.Stop(); // no harm in calling it
_oTimer.Dispose();
_shutdownEvent.Set(); // trigger the thread to stop
_thread.Join(); // wait for thread to stop
}
#Matt - thanks for the great code, really helpful.
I found it worked even better if I added another test on _shutdownEvent:
case 1: // Process Event
Process();
if(_shutdownEvent.WaitOne(0)) break; // don't loop again if a shutdown is needed
...
I have a multi thread application written by c#, my max thread number is 256 and this application gets the performance counters of the computers in an Ip interval(192.168.1.0 -192.168.205.255)
it works fine and turns many times in a day. because I have to get reports.
But the problem is some times one machine keeps a thread and never finishes its work so my loop doesnt turn...
Are there any way to create threads with a countdown parameter. when I start the threads in foreach?
foreach(Thread t in threads)
{
t.start(); -----> t.start(countdownParameter) etc....
}
coundown parameter is the max life of each threads. This mean if a thread cant reach a machine it have to be abort. for example 60 seconds.. no not 256 machines, I meant 256 threads... there are about 5000 ip and 600 of them are alive. soo I am using 256 threads to read their values. and the other thing is loop. my loop is working as while all off the ipies finish it starts from beginning.
You can't specify a timeout for thread execution. However, you can try to Join each thread with a timeout, and abort it if it doesn't exit.
foreach(Thread t in threads)
{
t.Start();
}
TimeSpan timeOut = TimeSpan.FromSeconds(10);
foreach(Thread t in threads)
{
if (!t.Join(timeOut))
{
// Still not complete after 10 seconds, abort
t.Abort();
}
}
There are of course more elegant ways to do it, like using WaitHandles with the WaitAll method (note that WaitAll is limited to 64 handles at a time on most implementations, and doesn't work on STA threads, like the UI thread)
You should not terminate the thread from the outside. (Never kill a thread, make it commit suicide). Killing a thread can easily corrupt the state of an appdomain if you're not very careful.
You should rewrite the network code in the threads to either time out once the time-limit has been reached, or use asynchronous network code.
Usually a thread gets stuck on a blocking call (unless of course you have a bug causing an infinite loop). You need to identify which call is blocking and "poke" it to get it to unblock. It could be that your thread is waiting inside one of the .NET BCL waiting calls (WaitHandle.WaitOne, etc.) in which case you could use Thread.Interrupt to unblock it. But, in your case it is more likely that the API managing the communication with the remote computers is hung. Sometimes you can simply close the connection from a separate thread and that will unblock the hung method (as is the case with the Socket class). If all else fails then you really might have to fall back on the method of last of calling Thread.Abort. Just keep in mind that if you abort a thread it might corrupt the state of the app domain in which the abort originated or even the entire process itself. There were a lot of provisions added in .NET 2.0 that make aborts a lot safer than they were before, but there is still some risk.
You can use smth like this:
public static T Exec<T>(Func<t> F, int Timeout, out bool Completed)
{
T result = default(T);
Thread thread = new Thread(() => result = F());
thread.Start();
Completed = thread.Join(Timeout);
if(!Completed) thread.Abort();
return result;
}
I need to do a sort of "timeout" or pause in my method for 10 seconds (10000 milliseconds), but I'm not sure if the following would work as i do not have multi-threading.
Thread.Sleep(10000);
I will try to use that current code, but I would appreciate if someone could explain the best and correct way of doing this, especially if the above code does not work properly. Thanks!
UPDATE: This program is actually a console application that in the function in question is doing many HTTPWebRequests to one server, so I wish to delay them for a specified amount of milliseconds. Thus, no callback is required - all that is needed is an "unconditional pause" - basically just the whole thing stops for 10 seconds and then keeps going. I'm pleased that C# still considers this as a thread, so Thread.Sleep(...) would work. Thanks everybody!
You may not have multi-threading, but you're still executing within a thread: all code executes in a thread.
Calling Thread.Sleep will indeed pause the current thread. Do you really want it to unconditionally pause for 10 seconds, or do you want to be able to be "woken up" by something else happening? If you're only actually using one thread, calling Sleep may well be the best way forward, but it will depend on the situation.
In particular, if you're writing a GUI app you don't want to use Thread.Sleep from the UI thread, as otherwise your whole app will become unresponsive for 10 seconds.
If you could give more information about your application, that would help us to advise you better.
Thread.Sleep is fine, and AFAIK the proper way. Even if you are not Multithreaded: There is always at least one Thread, and if you send that to sleep, it sleeps.
Another (bad) way is a spinlock, something like:
// Do never ever use this
private void DoNothing(){ }
private void KillCPU()
{
DateTime target = DateTime.Now.AddSeconds(10);
while(DateTime.Now < target) DoNothing();
DoStuffAfterWaiting10Seconds();
}
This is sadly still being used by people and while it will halt your program for 10 seconds, it will run at 100% CPU Utilization (Well, on Multi-Core systems it's one core).
That will indeed pause the executing thread/method for 10 seconds. Are you seeing a specific problem?
Note that you shouldn't Sleep the UI thread - it would be better to do a callback instead.
Note also that there are other ways of blocking a thread that allow simpler access to get it going again (if you find it is OK after 2s); such as Monitor.Wait(obj, 10000) (allowing another thread to Pulse if needed to wake it up):
static void Main() {
object lockObj = new object();
lock (lockObj) {
new Thread(GetInput).Start(lockObj);
Monitor.Wait(lockObj, 10000);
}
Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
Console.WriteLine("press return...");
string s = Console.ReadLine();
lock (state) {
Monitor.Pulse(state);
}
Console.WriteLine("GetInput exiting");
}
You can do this with Thread.Interrupt too, but IMO that is messier.
You could use a separate thread to do it:
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
Thread.Sleep(1000);
Console.WriteLine("done");
});
But, if this is a Windows Forms app, you will need to invoke the code after the delay from the Gui thread (this article, for example: How to update the GUI from another thread in C#?).
[Edit] Just saw your update. If it's a console app, then this will work. But if you haven't used multiple threads so far, then you need to be aware that this code will be executed in a different thread, which means you will have to take care about thread synchronization issues.
If you don't need background workers, stick to "keeping it simple".
Here is a pause class that will pause for the desired milliseconds and wont consume your CPU resources.
public class PauseClass
{
//(C) Michael Roberg
//Please feel free to distribute this class but include my credentials.
System.Timers.Timer pauseTimer = null;
public void BreakPause()
{
if (pauseTimer != null)
{
pauseTimer.Stop();
pauseTimer.Enabled = false;
}
}
public bool Pause(int miliseconds)
{
ThreadPriority CurrentPriority = Thread.CurrentThread.Priority;
if (miliseconds > 0)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
pauseTimer = new System.Timers.Timer();
pauseTimer.Elapsed += new ElapsedEventHandler(pauseTimer_Elapsed);
pauseTimer.Interval = miliseconds;
pauseTimer.Enabled = true;
while (pauseTimer.Enabled)
{
Thread.Sleep(10);
Application.DoEvents();
//pausThread.Sleep(1);
}
pauseTimer.Elapsed -= new ElapsedEventHandler(pauseTimer_Elapsed);
}
Thread.CurrentThread.Priority = CurrentPriority;
return true;
}
private void pauseTimer_Elapsed(object sender, ElapsedEventArgs e)
{
pauseTimer.Enabled = false;
}
}
Yes, that works just fine.
You don't have to have multiple threads to make use of some of the methods in the Thread class. You always have at least one thread.
For a timeout, you should have a static volatile boolean isRunning class field. When the new thread starts, the isRunning must become true, and at the end must become false.
The main thread should have a method that loops for the isRunning during the timeout you define. When the timeout ends, you should implement the logic. But, never use the abort thread method.
A pause... there isn't a straightforward solution. It depends on what you are doing inside the thread. However, you could look at Monitor.Wait.
If you can have an async method, you can do something like to pause the function at a certain location. Once pause is set false it will continue executing the rest of the code in the method. Since this is an async method and delay is async too UI execution wouldn't be affected.
* Please note that asyn is supported only in .net 4.5 and higher.
bool pause = true;
void async foo()
{
//some code
while (pause)
{
await Task.Delay(100);
}
//some code
}