Stopping System.Windows.Forms.Timer from another Thread Problem,...

  • Thread starter Kerem Gümrükcü
  • Start date
K

Kerem Gümrükcü

Hi,

i have a main thread an another worker thread.
The main Thread creates another thread and waits
for the threads signal to continue the main thread.
Everything works inside a ModalDialog and everyting
is secured by Invoke/BeginInvoke, and synchronisation
primitves like WaitHandles, Evetns, Semaphores, etc...
All works good and with no race conditions or locks.
I have a System.Windows.Forms.Timer in the main
Thread that must stopped from the second thread.
Using a code like does not stop the Timer and the
Message is obviousy clear to me, but how can i
stop the Timer on the Form from another Thread
that still s running? Thats what i get with that code:

private delegate void DisableTimerDelegate();
private void DisableTimer()
{
this.timerServiceTimeoutTimer.Enabled = false;
}

this.Invoke(new DisableTimerDelegate(this.DisableTimer));

Leads to this Exception:



System.InvalidOperationException: Invoke oder BeginInvoke kann für ein
Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde.
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate
method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei
DeviceRemover.Forms.DRKernelCommandProgressClass.ServiceCommandThread(Object
parameter) in
C:\projects\DeviceRemover\Forms\DRKernelCommandProgressClass.cs:Zeile 986.
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart(Object obj)

Translated says something like ""Invoke or BeginInvoke can only be called
for a Control if the WindowHandle has been created for it"

How can i "safely" stop that Timer from my second thread
in the main thread?

Thanks in advance,...

Regards

Kerem

--
 
M

Morten Wennevik [C# MVP]

Kerem Gümrükcü said:
Hi,

i have a main thread an another worker thread.
The main Thread creates another thread and waits
for the threads signal to continue the main thread.
Everything works inside a ModalDialog and everyting
is secured by Invoke/BeginInvoke, and synchronisation
primitves like WaitHandles, Evetns, Semaphores, etc...
All works good and with no race conditions or locks.
I have a System.Windows.Forms.Timer in the main
Thread that must stopped from the second thread.
Using a code like does not stop the Timer and the
Message is obviousy clear to me, but how can i
stop the Timer on the Form from another Thread
that still s running? Thats what i get with that code:

private delegate void DisableTimerDelegate();
private void DisableTimer()
{
this.timerServiceTimeoutTimer.Enabled = false;
}

this.Invoke(new DisableTimerDelegate(this.DisableTimer));

Leads to this Exception:



System.InvalidOperationException: Invoke oder BeginInvoke kann für ein
Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde.
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate
method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei
DeviceRemover.Forms.DRKernelCommandProgressClass.ServiceCommandThread(Object
parameter) in
C:\projects\DeviceRemover\Forms\DRKernelCommandProgressClass.cs:Zeile 986.
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart(Object obj)

Translated says something like ""Invoke or BeginInvoke can only be called
for a Control if the WindowHandle has been created for it"

How can i "safely" stop that Timer from my second thread
in the main thread?

Thanks in advance,...

Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.codeplex.com/restarts
Latest Open-Source Projects: http://entwicklung.junetz.de

Hi Kerem,

Stopping a Timer by invoking the main thread should be fine. It looks like
the Control holding the timer object has been closed, is not fully created,
or something causing it to not have a window handle.

You could try calling the method directly and have it check for
InvokeRequired and Handle existance etc.

private void DisableTimer()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(DisableTimer));
return;
}

if (Disposing || IsDisposed || Handle == IntPtr.Zero)
return;
else
this.timerServiceTimeoutTimer.Enabled = false;
}

You may want to use a System.Timers.Timer or System.Threading.Timer instead,
although then you may have to check for handle existance

PS! You don't need your own delegate to invoke void methods.
 
K

Kerem Gümrükcü

Hi Morten,

thanks for the answer. you say "PS! You don't need your own delegate to
invoke void methods.", so how
should or can i call a void delegate without a own delegate method?


Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.codeplex.com/restarts
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."
Morten Wennevik said:
Kerem Gümrükcü said:
Hi,

i have a main thread an another worker thread.
The main Thread creates another thread and waits
for the threads signal to continue the main thread.
Everything works inside a ModalDialog and everyting
is secured by Invoke/BeginInvoke, and synchronisation
primitves like WaitHandles, Evetns, Semaphores, etc...
All works good and with no race conditions or locks.
I have a System.Windows.Forms.Timer in the main
Thread that must stopped from the second thread.
Using a code like does not stop the Timer and the
Message is obviousy clear to me, but how can i
stop the Timer on the Form from another Thread
that still s running? Thats what i get with that code:

private delegate void DisableTimerDelegate();
private void DisableTimer()
{
this.timerServiceTimeoutTimer.Enabled = false;
}

this.Invoke(new DisableTimerDelegate(this.DisableTimer));

Leads to this Exception:



System.InvalidOperationException: Invoke oder BeginInvoke kann für ein
Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt
wurde.
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate
method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[]
args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei
DeviceRemover.Forms.DRKernelCommandProgressClass.ServiceCommandThread(Object
parameter) in
C:\projects\DeviceRemover\Forms\DRKernelCommandProgressClass.cs:Zeile
986.
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart(Object obj)

Translated says something like ""Invoke or BeginInvoke can only be called
for a Control if the WindowHandle has been created for it"

How can i "safely" stop that Timer from my second thread
in the main thread?

Thanks in advance,...

Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.codeplex.com/restarts
Latest Open-Source Projects: http://entwicklung.junetz.de

Hi Kerem,

Stopping a Timer by invoking the main thread should be fine. It looks
like
the Control holding the timer object has been closed, is not fully
created,
or something causing it to not have a window handle.

You could try calling the method directly and have it check for
InvokeRequired and Handle existance etc.

private void DisableTimer()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(DisableTimer));
return;
}

if (Disposing || IsDisposed || Handle == IntPtr.Zero)
return;
else
this.timerServiceTimeoutTimer.Enabled = false;
}

You may want to use a System.Timers.Timer or System.Threading.Timer
instead,
although then you may have to check for handle existance

PS! You don't need your own delegate to invoke void methods.
 
M

Morten Wennevik [C# MVP]

Kerem Gümrükcü said:
Hi Morten,

thanks for the answer. you say "PS! You don't need your own delegate to
invoke void methods.", so how
should or can i call a void delegate without a own delegate method?


Regards

Kerem

Hi Kerem,

..Net Framework has a built-in delegate for empty methods called MethodInvoker

Invoke(new MethodInvoker(VoidMethod));

This won't work if you need parameters, though. You don't have to use it if
you don't want to.
 
K

Kerem Gümrükcü

Hi Morten,
This won't work if you need parameters, though. You >don't have to use it
if
you don't want to.

yes, i know this way of invoking methods, but i thought
you might talk about something different, i did not know.
Thanks for the Code and Reply,...

Take care,...

Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Latest Project: http://www.codeplex.com/restarts
Latest Open-Source Projects: http://entwicklung.junetz.de
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top