Actually, when I want to stop my worker on azure, this function is called.
public override void OnStop()
{
if (messageProvider != null)
{
messageProvider.StopListening();
}
base.OnStop();
}
When I upgrade the worker, If there is any message beeing processed, I lose that message. Do you know how can I safely stop my worker?
You have five minutes, from the time OnStop() is called, and before OnStop() exits, to finish your current processing (whatever that means). In your case, it looks like you have some type of message provider, and you're able to disengage from message-consumption via messageProvider.StopListening();. Since you're concerned with processing of current message, you'd likely need some type of signal to let you know that there are no messages being processed (including ones that may have been read, but not processed, by the time you called StopListening()), and that it's safe to exit from OnStop(). How you implement the signal is up to you, but you'd need to wait for the signal within Onstop().
FYI info about OnStop() and the five-minute window is here.
Related
So after a long time of cursing and giving up hope I got everything to work (almost).
I have a GUI which displays a list of connected addresses and a list of messages. Normally when I close a connector (disconnect from an address) I write a message saying: "disconnected from address x". However as you will see from the methods, when disposing the application I cannot use the dispatcher to write that message (this.ModuleConnections.Remove(address); triggers the writing of the message and also removes it visually from the list).
private void CloseConnector(string address)
{
Task task = new Task(() =>
{
var moduleConnection = this.ModuleConnections[address];
moduleConnection.ModuleConnector.Dispose();
if (mDisposed == true)
{
ApplicationSupport.Dispatcher.Invoke(
DispatcherPriority.Background,
new Action(() =>
{
this.ModuleConnections.Remove(address);
}));
}
});
task.Start();
if (mDisposed == true)
{
mTasks.Add(task);
}
}
protected virtual void Dispose(bool disposing)
{
// Dispose managed resources.
if ((mDisposed == false) && (disposing == true))
{
mTasks.Clear();
mDisposed = true;
CloseConnectors();
Task.WaitAll(mTasks.ToArray());
}
}
I cannot use the dispatcher because Task.WaitAll stops the thread. If the thread is stopped the dispatcher cannot execute this.ModuleConnections.Remove(address); and this results in the task not finishing, if the tasks not finish Task.WaitAll won't release the thread. Which is a very big problem.
Without the task.waitall i would get a tremendous amount of object disposed and key not found exceptions and other nasty things which kept some threads running and thus the application wouldn't shut down completely.
But now, when it closes, the GUI freezes (looks like it crashed) for a few seconds and then (when task.waitall is finished) it closes the window and the entire application is closed correctly.
What I want is to still be able to update my list of messages and display what addresses have disconnected.
Just to clarify
I need the Task in the CloseConnector method because closing the connector (dispose) makes it disconnect, it needs to wait until it receives a message back from the other side before the code continues. if i were to run this 1 by one it would take minutes, in parallel as i do it now it only takes a few seconds.
First thing that I saw that you do not need to call Start() method for your task if you want to tun them all with WaitAll() menthod. Also if you want to run one task at a time, its better to use Task.Run() which takes Expression as an argument. The difference in this case is that Run() forces your task to start immediately while Start() can not guarantee that your task will be started now - it's just plan it to start with TaskScheduler. By the way, Wait() work in the same way
Finally, check your this object - what is this at this time? Is it not null? Maybe try to use closure and take your dispatcher as an arg
Hope that helps
Application logging is done using plain and boring log files via a custom rolling flat file logging library. To lower the amount of write accesses to the hard disk, logging events get queued for either when a) a maximum queue item limit is reached or b) a certain amount of time has passed. For the time interval aspect, the logging library runs a thread which flushes the queue periodically.
Now, the logging instance is statically accessible, singleton and application wide (used in many other libraries) and sometimes it happens (altough it shouldn't) that a developer forgets to dispose the flushing thread with the result that, even if the application is 'closed', the thread keeps running and the application has to be killed via a task-manager, which is far from ideal.
So I'm wondering: Is there a possibility to automatically close the thread on application exit? I know about BackgroundWorker, Timer and Threadpool, but are those good solutions for that certain task? Or better stick with the 'classic' Thread?
Detecting that an application is about to exit is very specific to what kind of application you're running.
I don't know much about Aspx, but in WPF you could use the following code to hook up the Exit event of the System.Windows.Application class and close your thread gracefully in the event handler.
Also, you should always avoid killing a thread instead of shutting down gracefully, when it's possible, it can lead to inconsistencies because you have no way of controlling when it will really exit. Instead, you should periodically check for an exit condition, like in the code below.
public static class MyLogger
{
public static void Initialize()
{
if(IsWPFApplication())
Application.Current.Exit += Application_Exit;
//start flush thread and other initializations...
}
private static bool IsWPFApplication()
{
Dispatcher dispatcher = Dispatcher.FromThread(Thread.CurrentThread);
return (dispatcher != null);
}
private static void Application_Exit(Object sender, EventArgs e)
{
Shutdown();
}
private static void Shutdown()
{
ExitRequested = true;
}
}
You can use System.Diagnostic.Process.GetCurrentProcess.Kill though if you are using dot net 4.0 I would recommend using tasks. Here is an excellent resource that I would recommend http://www.albahari.com/threading/.
I'm creating a program with several projects and some projects report back to the main project messages for logging purposes.
Since i am using Asynch sockets, some of these messages come back in different threads, so once they get to the main thread i check InvokeRequired and if true i use this.BeginInvoke to handle the logging.
I need to handle it in the UI thread specially in the case of the server, where i show the last logged messages on a ListBox so i can follow the progress of operations during my tests.
I know sometimes it may happen that a few messages get switched around, but for now i can live with that. For some reason if i use Invoke instead of BeginInvoke, the server will crash if i stop it while clients are connected, and won't even give any exception. But using BeginInvoke i overcame this.
My question regards understanding how events and BeginInvoke work in case of program termination. If an event is on queue or a BeginInvoke has been called just before the program is closed, will it terminate imediatly, cancelling everything? or will it perform all pending actions, in my case log the pending message, and then exit?
You'll have to delay closing the form if you want to ensure all BeginInvoked delegates are executed. You can do so by making it a two-step process, appending another BeginInvoke delegate to the queue that actually closes the form. Like this:
private bool closing;
protected override void OnFormClosing(FormClosingEventArgs e) {
if (!closing) {
closing = true;
// Do your stuff
//...
this.BeginInvoke(new Action(() => this.Close()));
e.Cancel = true;
}
base.OnFormClosing(e);
}
When you call BeginInvoke to update UI, the code will be executed by a thread from the threadpool. And if the code raises an exception, it will only terminate the thread, not the whole application. That's why you have seen that your program didn't crash.
When BeginInvoke had just been called, and the program was terminated immediately. The remaining operations (logging ) won't be executed, because the thread from the threadpool
I'm creating a windows service and after installing the service, it stops and starts immediately, but it shouldn't be at all. Previously, I was getting errors that the service was not responding to the start command in a timely fashion, so I took the init code out and put it in a thread, and now I am here:
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("ATNotifier Started");
ThreadPool.QueueUserWorkItem(WaitOnEmailsChanged);
ThreadPool.QueueUserWorkItem(Init, "IP");
}
The waitonemailschanged thread simply creates a filesystemwatcher to watch to see if the settings file (xml document) gets changed, and loads in the data from that file if that happens. For the time being, this just waits indefinitely (which is the general case, as that will only be changed a few times a year), as no changes are being made to the xml document.
The Init thread does all kinds of things, including creating and starting a System.Timers.Timer object whose Elapsed method is the meat of the service.
I can't understand why it would start and then immediately stop. I should also note that the eventviewer shows no logs from this app.
edit> I tried creating 'proper' threads, with the same results and I've removed everything except the creating and starting of the timer like so:
protected override void OnStart(string[] args)
{
this.EventLog.WriteEntry("ATNotifier Started");
m_Timer = new System.Timers.Timer(90000.0); // 1.5 mins
m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
m_Timer.Start();
}
and I'm still getting the same message. It's almost as if the OnStart is never being called.
It might be stopped unexpectedly if your main thread terminates on exception.
The code you posted doesn't make sense to me. Why set an event handler before creating your Timer?
m_Timer.Elapsed += new ElapsedEventHandler(m_Timer_Elapsed);
m_Timer = new System.Timers.Timer(90000.0); // 1.5 mins
Shouldn't these two lines be swapped?
The problem turned out top be that the EventLog.WriteEntry was throwing an error because there was no EventSource associated with it. see http://msdn.microsoft.com/en-us/library/xzwc042w.aspx
As far as I can recall, you must actively report to the service manager that the service has successfully started - otherwise, the OnStart method will return, and if the status change has not been reported, the service manager will assume that the service terminated without actually successfully loading itself.
Reporting your service as having started successfully is done IIRC by the Service base class, so add the following to the bottom of the OnStart method:
base.OnStart(args);
ThreadPool threads are background threads; they won't keep a process alive. I suspect you need a "proper" thread...
Try: new Thread(SomeCode).Start(); or similar.
I have an object, a Timeline, that encapsulates a thread. Events can be scheduled on the timeline; the thread will wait until it is time to execute any event, execute it, and go back to sleep (for either (a) the time it takes to get to the next event or (b) indefinitely if there are no more events).
The sleeping is handled with a WaitEventHandle, which is triggered when the list of event is altered (because the sleep delay may need to be adjusted) or when the thread should be stopped (so the thread can terminate gracefully).
The destructor calls Stop(), and I've even implemented IDisposable and Dispose() also calls Stop().
Still, when I use this component in a forms application, my application will never shut down properly when I close the form. For some reason, Stop() is never called, so neither my object's destructor triggers, nor is the Dispose() method called, before .NET decides to wait for all threads to finish.
I suppose the solution would be to explicitly call Dispose() myself on the FormClose event, but since this class is going to be in a library, and it is actually a layer deeper (that is, the application developer will never actually see the Timeline class), this seems very ugly and an extra (unnecessary) gotcha for the application developer. The using() clause, which I would normally use when resource release becomes an issue, doesn't apply as this is going to be a long-lived object.
On the one hand, I can understand that .NET will want to wait for all threads to finish before it does its final round of garbage collection, but in this case that produces a very clumsy situation.
How can I make my thread clean up after itself properly without adding requirements to consumers of my library? Put another way, how can I make .NET notify my object when the application is exiting, but before it will wait for all threads to finish?
EDIT: In response to the people saying that it is ok for the client program to be aware of the thread: I respectfully disagree.
As I said in my original post, the thread is hidden away in another object (an Animator). I instantiate an Animator for another object, and I tell it to perform animations, such as "blink this light for 800ms".
As a consumer of the Animator object, I do not care how the Animator makes sure that the light blinks for exactly 800ms. Does it start a thread? I don't care. Does it create a hidden window and use system timers (ew)? I don't care. Does it hire midgets to turn my light on and off? I don't care.
And I especially don't want to have to care that if I ever create an Animator, I have to keep track of it and call a special method when my program exits, in contrast to every other object. It should be a concern of the library implementor, not the library consumer.
EDIT: The code is actually short enough to show. I'll include it for reference, sans methods that add events to the list:
internal class Timeline : IDisposable {
private Thread eventThread;
private volatile bool active;
private SortedList<DateTime, MethodInvoker> events = new SortedList<DateTime,MethodInvoker>();
private EventWaitHandle wakeup = new EventWaitHandle(false, EventResetMode.AutoReset);
internal Timeline() {
active = true;
eventThread = new Thread(executeEvents);
eventThread.Start();
}
~Timeline() {
Dispose();
}
private DateTime NextEvent {
get {
lock(events)
return events.Keys[0];
}
}
private void executeEvents() {
while (active) {
// Process all events that are due
while (events.Count > 0 && NextEvent <= DateTime.Now) {
lock(events) {
events.Values[0]();
events.RemoveAt(0);
}
}
// Wait for the next event, or until one is scheduled
if (events.Count > 0)
wakeup.WaitOne((int)(NextEvent - DateTime.Now).TotalMilliseconds);
else
wakeup.WaitOne();
}
}
internal void Stop() {
active = false;
wakeup.Set();
}
public void Dispose() {
Stop();
}
}
Maybe set the Thread.IsBackground property to true?
eventThread = new Thread(executeEvents);
eventThread.IsBackground = true;
eventThread.Start();
Another option is to use the Interrupt method to wake it up. Just make sure that you catch the ThreadInterruptedException in the thread that you are interrupting, and that it shuts down when it happens.
active = false;
eventThread.Interrupt();
try { eventThread.Join(); } // Wait for graceful shutdown
catch (Exception) { }
Not quite sure how that EventWaitHandle of yours works though... When I did something similar once, I just used the regular Thread.Sleep =)
I don't think it is unreasonable to require clients to Stop() the thread for shutdown at all. There are ways you can create threads whose continued execution will not stop the application from exiting (although I don't have the details off the top of my head). But expecting to launch and terminate a worker thread is not too much of a burden for the client.
There is no way to get .NET to notify your thread without the clients cooperation. If you're designing your library to have a long running background thread, then the client app has to be designed to know about it.
Application::ApplicationExit is a static event, is it acceptable to listen for it and do your special cleanup work?
Implementing IDisposable should be enough indication that your clients should be using your class in a "using" block.
Implement IDisposable properly, including implementing a finaliser that calls Dispose(true). You Animator object can then do any clean up it wishes to, including stopping the thread if necessary.