Guys, I have a Windows App that I have created using C# (which, considering the lack of training I have in C#, is no small feat ;-). However, I now have a need to have a timer set so that this app will auto-close after certain actions are completed. Apparently, though, if I set a timer and the timer fires, calling an event handler I specify, that event handler can’t close the Windows form because it is not in the same thread. Therefore, I posit this question: How do I accomplish setting a controllable delay in the closing of the Windows form (i.e. my app)? Respectfully, Ralph D. Wilson II Senior Programmer Analyst Information Technology Department 9311 San Pedro Suite 600 San Antonio TX 78216 (800) 527-0066 x7368 (210) 321-7368 (direct) email@removed “Make everything as simple as possible, but not simpler.” Albert Einstein.

EVERYONE,

THIS THREAD IS DEAD! The problem was solved LONG ago and, if had not
been, you would be FAR too late with your advise.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.
“Give me six hours to chop down a tree and I will spend the first four
sharpening the axe.” - Abraham Lincoln

“Tonci Korsano via csharp-l”

Rohit,

This is a true moldy-oldy question that I have resolved quite some time
back. I received several nonproductive answers and figured this one out
on my own.

However, I do applaud your enthusiasm. :wink:

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.
“Give me six hours to chop down a tree and I will spend the first four
sharpening the axe.” - Abraham Lincoln

“Rohit Arora via csharp-l”

I haven’t tried the following, but try Environment.Exit(-some number like 0-);
and let us know whether that worked for you.

Best regards,

Tonci,
From: csharp-l@Groups.ITtoolbox.comTo: tkorsano@hotmail.comDate: Tue, 9 Dec 2008 04:23:18 -0500Subject: RE:[csharp-l] I need to automatically close a C# Windows App
try Application.Exit ();

try Application.Exit ();

Tarik, et al,

As I have previously indicted, this boat has sailed! There is no need
for additional threads (or posts to this thread ;-). I SOLVED THE
PROBLEM.

I HAVE MOVED ON!

All of these esoteric solutions pale, IMHO, to the one I used. Since the
interval for the processing is small and the need to display the data is
relatively minor, I had the app display the data and then sleep for
approximately the same amount of time that the timer was set for and, sure
enough, almost immediately after reactivating, the app closes the form. My
problem was that the close was being attempted in the Constructor.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

“Tarik Kucuk via csharp-l”

Hello,

Please use a thread (if it is a really necessary) for to run your special part of codes which could be done before closing the form. In this procedure, you need a lock object (is an intance of object) and use it in your code should looks like this ;


object mylock = new object(); ← In main thread

void SomeWork(){
lock(mylock)
{
… ← your special
}
}

run SomeWork with a different Thread object, do not use main thread!!!. In the OnClose() method of MainForm you should use the same instance of lock object.

void OnClose(…){
lock(mylock){ ← here is the waiting point

this block will be process after the SomeWork() comleted

}
}

I hope this pseudue code will be helpfull.
Regards.

David,

See my respons to Payton. :wink:

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

“ddavison via csharp-l”

Payton,

Sorry but this boat sailed a long time ago. The problem has been solved
and the app has been rolled out but I do appreciate you offerings.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

“PaytonByrd via csharp-l”

Have the timer trigger an event object ( the event should be created as part of the form )? I don’t know that the event object code will be on the required thread either.

Looks like the remainder of the code got cut off. Here it is:

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 264);
this.Controls.Add(this.label1);
this.Name = “frmTimers”;
this.Text = “frmTimers”;
this.Load += new System.EventHandler(this.frmTimers_Load);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmTimers_FormClosed);
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Timer shutdownTimer;
private System.Windows.Forms.Timer tickTimer;
private System.Windows.Forms.Label label1;
}
}

@Ralph!

I couldn’t help but throw in my 2 cents here. :slight_smile:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Timer_Example
{
public partial class frmTimers : Form
{
public frmTimers()
{
InitializeComponent();
}

private void tickTimer_Tick(object sender, EventArgs e)
{
lock (this)
{
tickTimer.Enabled = false;
label1.AutoSize = true;
label1.Text = DateTime.Now.ToLongTimeString();

System.Diagnostics.Debug.WriteLine(“tickTimer_Tick!”);

tickTimer.Enabled = true;
}
}

private void shutdownTimer_Tick(object sender, EventArgs e)
{
lock (this)
{
tickTimer.Enabled = false;
shutdownTimer.Enabled = false;

label1.Text = “Shutting down in 10 seconds.”;
System.Diagnostics.Debug.WriteLine(“shutdownTimer_Tick!”);

System.Threading.Thread.Sleep(10000);

this.Close();
}
}

private void frmTimers_Load(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(“frmTimers_Load!”);
tickTimer.Enabled = true;
shutdownTimer.Enabled = true;
}

private void frmTimers_FormClosed(object sender, FormClosedEventArgs e)
{
tickTimer.Dispose();
shutdownTimer.Dispose();
System.Diagnostics.Debug.WriteLine(“frmTimers_FormClosed!”);
}
}
}

The trick is to use the System.Windows.Forms.Timer object which is built to do exactly what you are looking for.

Here’s the designer partial class:

namespace Timer_Example
{
partial class frmTimers
{
///
private System.ComponentModel.IContainer components = null;

///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

///
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.shutdownTimer = new System.Windows.Forms.Timer(this.components);
this.tickTimer = new System.Windows.Forms.Timer(this.components);
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// shutdownTimer
//
this.shutdownTimer.Interval = 10000;
this.shutdownTimer.Tick += new System.EventHandler(this.shutdownTimer_Tick);
//
// tickTimer
//
this.tickTimer.Interval = 1000;
this.tickTimer.Tick += new System.EventHandler(this.tickTimer_Tick);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = “label1”;
this.label1.Size = new System.Drawing.Size(40, 13);
this.label1.TabIndex = 0;
this.label1.Text = “lblTime”;
//
// frmTimers
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 264);
this.Controls.Add(this.label1);
this.Name = “frmTimers”;
this.Text = “frmTimers”;
this.Load += new System.EventHandler(this.frmTimers_Load);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.frmTimers_FormClosed);
this.ResumeLayout(false);
this.PerformLayout();

}

#endregion

private System.Windows.Forms.Timer shutdownTimer;
private System.Windows.Forms.Timer tickTimer;
private System.Windows.Forms.Label label1;
}
}

cws2,

That would be handy . . . except for the fact that this is not going to be
an app executed by your typical User. This one is destined to be run via
Windows Task Manager on a server and, therefore, the User will never
really be at their workstation. The purpose of the form is to provide the
ability to let someone who may happen to be logged onto the server when
the app executes (or who may log onto the server in order to manually kick
off the app :wink: to a) see what is running and/or b) see that it is
running.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

“cws2 via csharp-l”

I don’t have any code, but instead of polling one could use an Event object, trigger it where you set “NeedToClose” to true, and have the handler for the Event object do the application exit. Burn fewer cycles that way.
David

Hello all, I’m late to this thread, I see Ralph has already solved his problem.
Anyway, thought I’d post this just to present another possible solution [by no means the best or cleanest].
The code below compares the current time with the time the user logged in against a defined interval,
and displays a dialog to the user. If the user is still at their workstation, they have [in this case] 30 seconds
to notice the message and click a “Keep Working” button. Otherwise, the user is automatically logged out
and the application shuts down.
The main point of this example, let the .Net framework do the heavy lifting:
// object passed to secondary or background thread from the main thread
class StateObject : Object
{
private string m_sActivityDelayPeriod = “minute”; //default to minutes
public string ActivityDelayPeriod { get { return m_sActivityDelayPeriod; } set { m_sActivityDelayPeriod = value; } }
private string m_nActivityDelayValue = “60”; //default to 60
public string ActivityDelayValue { get { return m_nActivityDelayValue; } set { m_nActivityDelayValue = value; } }
private DateTime m_dtLastLogon = DateTime.Now; //default to now
public DateTime LastLogonDateTime { get { return m_dtLastLogon; } set { m_dtLastLogon = value; } }
private Form m_formInstance = null;
public Form ParentForm { get { return m_formInstance; } set { m_formInstance = value; } }
}

//…in the application’s mainform load event or at completion of authentication event…
StateObject oCurrentState = new StateObject();
oCurrentState.ParentForm = this;
//override defaults
oCurrentState.ActivityDelayPeriod = “hour”;
oCurrentState.ActivityDelayValue = “4”;
oCurrentState.LastLogonDateTime = DateTime.Now;
//…queue this to a background thread…
ThreadPool.QueueUserWorkItem(checkInterval, oCurrentState);

private void checkInterval(object obj)
{
StateObject m_obj = (StateObject)obj;
DateTime dtNow = DateTime.Now;
bool bRun = true;
int nDelayValue = Convert.ToInt32(m_obj.ActivityDelayValue);
while (bRun)
{
int nLogonValue = (int)m_obj.LastLogonDateTime.TimeOfDay.TotalHours;
int nIntervalNow = (int)dtNow.TimeOfDay.TotalHours;
//is it time to display the log out dialog…?
if ((nIntervalNow - nLogonValue) >= nDelayValue)
{
fMain m_frm = ((fMain)m_obj.ParentForm);
m_frm.showWarning();
if (m_frm.KeepWorking)
{
m_obj.LastLogonDateTime = DateTime.Now;
continue;
}
bRun = false;
break;
}
dtNow = DateTime.Now;
Thread.Sleep(15000);
}
}
//use a delegate and the InvokeRequired option for ui updates from a secondary thread
delegate void genericDelegate();
public void showWarning()
{
if (this.InvokeRequired)
{
//generic delegate
showWarningCallBack d = new genericDelegate(showWarning);
this.Invoke(d, new object { });
}
else
{
dlgTimed dlgWarn = new dlgTimed();
dlgWarn.Message = "Warning! This application has exceeded the allowed " +
System.Environment.NewLine + "login period and will shut down in: ";
dlgWarn.DelaySeconds = 30;
dlgWarn.ShowDialog();
//user elected to keep working
if (dlgWarn.KeepWorking)
{
return;
}
ForceLogout();
}
}
private void ForceLogout()
{
if (this.InvokeRequired)
{
closeFormCallBack d = new genericDelegate(ForceLogout);
this.Invoke(d, new object { });
}
else
{
//
//Perform logout or necessary actions before closing app…
//
//finally close the main form
this.Close();
}
}

//excerpt from dialog **********************************************************************
//The dlgTimed form is a standard winform form, shown as a modal dialog
private void dlgTimed_Load(object sender, EventArgs e)
{
timer1.Interval = (1000);
timer1.Start();
//this will display the warning message as set via the property
lblMessage.Text = m_sMessage + " " + DelaySeconds.ToString() + " seconds.";
}

private void timer1_Tick(object sender, EventArgs e)
{
DelaySeconds–;
lblMessage.Text = m_sMessage + " " + DelaySeconds.ToString() + " seconds.";
if (DelaySeconds == 0)
{
timer1.Stop();
this.Close();
}
}
private void btnClickMeToKeepWorking_Click(object sender, EventArgs e)
{
m_bKeepWorking = true;
timer1.Stop();
//close this dialog…
this.Close();
}

//excerpt from dialog **********************************************************************

This might be simplistic, but If you put a timer component on the form, with
the timeout you want, set to enabled=true, and subscribe to the Tick event,
you can do the following:
private void timer1_Tick(object sender, EventArgs e)
{
Application.Exit();
}
putting the timer in as a component gets the timer tick event back to the UI
thread, where the application exit can occur.

Hi Ralph,

I am getting old… By surfing I found out you shouldnt use Application.DoEvents() in .net framework.
Also, Thread.Abort() will cause an exception.
Looks like you can self-document on Environment.Exit(0) with error code in parentheses. I haven’t tried though.
Application.Exit vs. Environment.Exit - Geeks with Blogs for environment.exit
And also, looks like doevents should be replaced by BackgroundWorker in .net framework.
I would try first Environment.Exit(0) Usually zero is no error ocurred. Let us know whether that works.

Good luck,

Tonci.
To: tkorsano@hotmail.comSubject: RE: [csharp-l] I need to automatically close a C# Windows AppFrom: csharp-l@Groups.ITtoolbox.comDate: Fri, 7 Nov 2008 13:05:57 -0600
All, What I currently have coded at the end of the constructor for the form is: ShutDownTimer = new System.Timers.Timer(15000); ShutDownTimer.Elapsed += new ElapsedEventHandler(ShutDownTheApp); ShutDownTimer.AutoReset = false; ShutDownTimer.Enabled = true; Application.DoEvents(); NeedToClose = false; while (!NeedToClose) { Application.DoEvents(); System.Threading.Thread.Sleep(1000); lstbxConfiguration.Items.Add("NeedToClose: " + NeedToClose.ToString()); } Application.ExitThread(); The “ShutDownTheApp” event handler sets he NeedToClose value to True; What is happening is that the app now displays the various lstbxConfiguration.Items that I have added through the processing along with the 14 instances of “NeedToClose: false” and the one, final instance of “NeedToClose: true” . . . all of which displays the first time the form displays. I have tried using “Application.Exit();” and “Close();” but the form doesn’t want to shut down and the app won’t exit. Respectfully, Ralph D. Wilson II Senior Programmer Analyst Information Technology Department 9311 San Pedro Suite 600 San Antonio TX 78216 (800) 527-0066 x7368 (210) 321-7368 (direct) ralphwilson@swbc.com “Make everything as simple as possible, but not simpler.” Albert Einstein. “Hubers, Wayne via csharp-l”

All,

I have resolved the problem. It turns out that I needed to move my
processing and shut down steps to another event. I moved it to the Shown
event and it now works as desired.

Ah, yes, some of the features I habitually use in Delphi are sorely
missed. Delphi has a Timer component that is part of the app and lets you
do things within the same thread as the app. C#'s system.timer is in
it’s own thread and, therefore, there are things the ElapsedEventHandler
can’t do.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

Dave,

I tried putting "Close(); where the “Application.Exit();” line is and that
throws an exception as well.

So, at this point, my question reduces to, “How do I programmatically
cause the main form of an application to close without human
intervention?”

I am assuming that the entire app will shut down once the form closes.

Respectfully,
Ralph D. Wilson II
Senior Programmer Analyst
Information Technology Department
9311 San Pedro Suite 600
San Antonio TX 78216
(800) 527-0066 x7368
(210) 321-7368 (direct)
ralphwilson@swbc.com
“Make everything as simple as possible, but not simpler.” Albert
Einstein.

“David M. Sterling via csharp-l”

You are running in two processes - you need to locate the form process and close that
before you close the app.

Best Regards,

David M. Sterling
david_sterling@sterling-consulting.com
Office (US Only): (888) 847-3679 x 704
Office: +1 (704) 664-8400 x 704
Mobile: +1 (704) 202-2282
Author: Microsoft Office SharePoint Server 2007: The Complete Reference
(Osborne/McGraw-Hill); available World Wide
Co-Author: Microsoft SharePoint Technologies Resource Kit 2003 (Microsoft Press)

SicgTxtLogo
www.sterling-consulting.com
Sterling International Consulting Group
+1 (704) 664-8400 - US: (888)847-3679

SICG_Gold_Partner
SharePoint Technologies Experts
Management Consultants
Technical Architects and Advisors

Alliance Partners:
IQ Software (Romania), Foundation IT, LLC (UK)