I have a C # / TCP / Winform application that has been running for quite some time, but one of my users has discovered a problem that I can easily replicate, but I cannot solve the problem.
If the application is open in Windows 7, and the user then changes any parameter in the screensaver settings - whether it is the screen saver or the time - the application freezes and the user interface becomes unresponsive. Clicking anywhere on the form simply gets the ding system.
When the application starts through Visual Studio in debug mode, the problem ceases to exist, but one day, from within the VS, it returns to freezing.
After some mastering and testing, I seem to narrow my problem down to System.Threading.Timer, which runs once per second. I relentlessly parse what the timer does, and find that even if the timer event does nothing, it still blocks the application. If I turn off the timer in the code or cancel the timer in the application before changing the Screensaver settings, the application will return to the functionality after changing the screen saver (although it still freezes for about 2-3 seconds).
This code here seems to be all that is needed for the application to freeze (inside WinForm code):
private void startCountDownTimer()
{
Object timeState = new object();
this._timerCall = new System.Threading.TimerCallback(this.countDown);
this._countdownTimer = new System.Threading.Timer(_timerCall, timeState, 0, 1000);
}
private void countDown(Object state)
{
}
Note that this freeze occurs even though the contents of countDown are commented out so that the timer does nothing but fire once per second.
, , , - . - "":
, EndTask. EndTask , , :
A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll
===================================
ERR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.BeginInvoke(Delegate method)
at Wcsg.UI.Windows.CadClient.client_MessageReceived(TcpMessageReceivedEventArgs mrea) in C:\Users\---------\Documents\Visual Studio 2010\Projects\Dispatch-DEVELOPMENT\CadClient\Forms\CadClientForm.cs
at Wcsg.Net.Tcp.WcsgTcpClient.processStream(Int32 count)
at Wcsg.Net.Tcp.WcsgTcpClient.performSocketRead(IAsyncResult ar)
---------------------
, , , , -, , , , .
, .
* *
Main , (. ) . :
[STAThread]
static void Main(String[] args)
{
bool createdNew = _mutex.WaitOne(TimeSpan.Zero, false);
if (createdNew)
{
List<String> newArgs = new List<string>(args);
newArgs.Add("-SM");
args = newArgs.ToArray();
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppDomain currentDomain = AppDomain.CurrentDomain;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
CadClient cc = new CadClient(args);
CadExceptionHandler ceh = new CadExceptionHandler(ref cc);
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(ceh.CurrentDomain_UnhandledException);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(ceh.Application_ThreadException);
Application.Run(cc);
}
* *
, Splashscreen:
private void showSplashScreen()
{
WaitCallback wcb = new WaitCallback(doSplashScreen);
ThreadPool.QueueUserWorkItem(wcb);
}
private void doSplashScreen(object state)
{
if (this._splash == null)
this._splash = new SplashForm(this);
this._splash.FormClosed += new FormClosedEventHandler(_splash_FormClosed);
this._splash.Show();
while (this._splash != null && !this._splash.WorkDone)
Application.DoEvents();
this._splash.Close();
}
showSplashScreen() - InitializeComponents(). , . , udpates, . ( ), , SplashScreen .