Click here to Skip to main content
15,867,834 members
Please Sign up or sign in to vote.
1.22/5 (2 votes)
See more:
How can I run timer1_Tick on separate thread ?
I searched everywhere on google and I can't find anything.
Posted
Updated 13-Dec-16 14:04pm

You did not find anything simply because there is nothing special about a timer and a thread. How do you think, if you asked "how to find a sub-string on a separate thread" or "how to write a file in a separate thread", would you find a definitive answer? No. Because it does not matter what thread. And what is "separate"? Separate from what?

There can be another reason: there is no such event "timer1_Tick". This is just a method name, it can be anything.

There are at least three different timers: System.Threading.Timer, System.Timers.Timer and System.Windows.Forms.Timer, I listed them in the order, roughly speaking, from low-lever to high-level. Fist timer does not have events, only a callback, which is a delegate. The second timer has events Disposed and Elapsed, and the third timer has to event Tick. So, your question most likely is about System.Windows.Forms.Timer. How to use it in a "separate" thread? As this timer "belongs" to Forms UI, the "separate" should probably mean "from the thread other then UI thread".

Short answer is: don't use it, even "from" the UI thread. This timer is notoriously inaccurate. Use it, but only on UI thread (you can do it on non-UI thread with some precautions (see below), but in this case you loose its only benefit — fool-proof simplicity). So, if you poorly understand thread, invocation mechanism (see below) and don't care about accuracy (really don't care, because what you get can be remarkably bad), you can use it. You should operate this timer in UI thread, but in the handler of its Tick method you can also use it in assumption that this is the same UI thread, so you can call UI methods and properties.

If you need some quality, use any of the other timers. In the callback or event handler, however, you cannot call any methods and properties. You can call them indirectly from UI thread using UI thread invocation mechanism. You will need to use method Invoke or BeginInvoke of the class System.Threading.Dispatcher (WPF or Forms) or System.Windows.Forms.Control (naturally, for Forms only; you can use any instance of control participating in currently running Application).
For detailed explanation of the invocation mechanism and code samples, see my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

That said, with these two timers it does not matter in what thread they are used.

That comes to the final idea: don't use any timers at all if you can use threads instead. With timers, you will get much more troubles. Did you even tried to design software taking in consideration the following possibility: what to do if next timer event if fired when the processing in the handler triggered by a previous event is not yet finished? This is just the hint. With threads, there are no such problems.
Please see my past answers on the topic:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 
v3
Comments
SKOTAJI 6-May-11 22:22pm    
Nice explanation. voted 5.
Sergey Alexandrovich Kryukov 6-May-11 23:10pm    
I would say, you did not... just yet.
Thank you.
--SA
Sandeep Mewara 6-May-11 23:24pm    
5+!
Sergey Alexandrovich Kryukov 6-May-11 23:55pm    
Thank you, Sandeep.
--SA
In brief - as SAKryukov has indicated, don't use the System.Windows.Forms.Timer if you want the Tick handler on a separate thread - it is designed specifically to call on the UI thread.

Instead use a System.Timers.Timer and it's Elapsed event which will be called on the thread the timer is automatically allocated (non UI).
 
Share this answer
 
Provides a mechanism for executing a method at specified intervals. This class cannot be inherited.
Inheritance Hierarchy
System.Object
System.MarshalByRefObject
System.Threading.Timer

Namespace: System.Threading
Assembly: mscorlib (in mscorlib.dll)
Syntax
C#
C++
F#
VB

[ComVisibleAttribute(true)]
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true,
ExternalThreading = true)]
public sealed class Timer : MarshalByRefObject,
IDisposable

The Timer type exposes the following members.
Constructors
Name Description
Public method Timer(TimerCallback) Initializes a new instance of the Timer class with an infinite period and an infinite due time, using the newly created Timer object as the state object.
Public method Supported by the XNA Framework Supported by Portable Class Library Timer(TimerCallback, Object, Int32, Int32) Initializes a new instance of the Timer class, using a 32-bit signed integer to specify the time interval.
Public method Supported by the XNA Framework Timer(TimerCallback, Object, Int64, Int64) Initializes a new instance of the Timer class, using 64-bit signed integers to measure time intervals.
Public method Supported by the XNA Framework Supported by Portable Class Library Timer(TimerCallback, Object, TimeSpan, TimeSpan) Initializes a new instance of the Timer class, using TimeSpan values to measure time intervals.
Public method Supported by the XNA Framework Timer(TimerCallback, Object, UInt32, UInt32) Initializes a new instance of the Timer class, using 32-bit unsigned integers to measure time intervals.
Top
Methods
Name Description
Public method Supported by the XNA Framework Supported by Portable Class Library Change(Int32, Int32) Changes the start time and the interval between method invocations for a timer, using 32-bit signed integers to measure time intervals.
Public method Supported by the XNA Framework Change(Int64, Int64) Changes the start time and the interval between method invocations for a timer, using 64-bit signed integers to measure time intervals.
Public method Supported by the XNA Framework Supported by Portable Class Library Change(TimeSpan, TimeSpan) Changes the start time and the interval between method invocations for a timer, using TimeSpan values to measure time intervals.
Public method Supported by the XNA Framework Change(UInt32, UInt32) Changes the start time and the interval between method invocations for a timer, using 32-bit unsigned integers to measure time intervals.
Public method CreateObjRef Creates an object that contains all the relevant information required to generate a proxy used to communicate with a remote object. (Inherited from MarshalByRefObject.)
Public method Supported by the XNA Framework Supported by Portable Class Library Dispose Releases all resources used by the current instance of Timer.
Public method Dispose(WaitHandle) Releases all resources used by the current instance of Timer and signals when the timer has been disposed of.
Public method Supported by the XNA Framework Supported by Portable Class Library Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected method Supported by the XNA Framework Supported by Portable Class Library Finalize Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.)
Public method Supported by the XNA Framework Supported by Portable Class Library GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public method GetLifetimeService Retrieves the current lifetime service object that controls the lifetime policy for this instance. (Inherited from MarshalByRefObject.)
Public method Supported by the XNA Framework Supported by Portable Class Library GetType Gets the Type of the current instance. (Inherited from Object.)
Public method InitializeLifetimeService Obtains a lifetime service object to control the lifetime policy for this instance. (Inherited from MarshalByRefObject.)
Protected method Supported by the XNA Framework Supported by Portable Class Library MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Protected method MemberwiseClone(Boolean) Creates a shallow copy of the current MarshalByRefObject object. (Inherited from MarshalByRefObject.)
Public method Supported by the XNA Framework Supported by Portable Class Library ToString Returns a string that represents the current object. (Inherited from Object.)
Top
Remarks

Use a TimerCallback delegate to specify the method you want the Timer to execute. The timer delegate is specified when the timer is constructed, and cannot be changed. The method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system.

When you create a timer, you can specify an amount of time to wait before the first execution of the method (due time), and an amount of time to wait between subsequent executions (period). You can change these values, or disable the timer, using the Change method.
Note Note

As long as you are using a Timer, you must keep a reference to it. As with any managed object, a Timer is subject to garbage collection when there are no references to it. The fact that a Timer is still active does not prevent it from being collected.

When a timer is no longer needed, use the Dispose method to free the resources held by the timer. Note that callbacks can occur after the Dispose method overload has been called, because the timer queues callbacks for execution by thread pool threads. You can use the Dispose(WaitHandle) method overload to wait until all callbacks have completed.

The callback method executed by the timer should be reentrant, because it is called on ThreadPool threads. The callback can be executed simultaneously on two thread pool threads if the timer interval is less than the time required to execute the callback, or if all thread pool threads are in use and the callback is queued multiple times.
Note Note

System.Threading.Timer is a simple, lightweight timer that uses callback methods and is served by thread pool threads. It is not recommended for use with Windows Forms, because its callbacks do not occur on the user interface thread. System.Windows.Forms.Timer is a better choice for use with Windows Forms. For server-based timer functionality, you might consider using System.Timers.Timer, which raises events and has additional features.
Note Note

The HostProtectionAttribute attribute applied to this type or member has the following Resources property value: Synchronization | ExternalThreading. The HostProtectionAttribute does not affect desktop applications (which are typically started by double-clicking an icon, typing a command, or entering a URL in a browser). For more information, see the HostProtectionAttribute class or SQL Server Programming and Host Protection Attributes.
Examples

The following code example demonstrates the features of the Timer class.
C#
C++
VB

C#
using System;
using System.Threading;

class TimerExample
{
    static void Main()
    {
        // Create an event to signal the timeout count threshold in the
        // timer callback.
        AutoResetEvent autoEvent     = new AutoResetEvent(false);

        StatusChecker  statusChecker = new StatusChecker(10);

        // Create an inferred delegate that invokes methods for the timer.
        TimerCallback tcb = statusChecker.CheckStatus;

        // Create a timer that signals the delegate to invoke 
        // CheckStatus after one second, and every 1/4 second 
        // thereafter.
        Console.WriteLine("{0} Creating timer.\n", 
            DateTime.Now.ToString("h:mm:ss.fff"));
        Timer stateTimer = new Timer(tcb, autoEvent, 1000, 250);

        // When autoEvent signals, change the period to every
        // 1/2 second.
        autoEvent.WaitOne(5000, false);
        stateTimer.Change(0, 500);
        Console.WriteLine("\nChanging period.\n");

        // When autoEvent signals the second time, dispose of 
        // the timer.
        autoEvent.WaitOne(5000, false);
        stateTimer.Dispose();
        Console.WriteLine("\nDestroying timer.");
    }
}

class StatusChecker
{
    private int invokeCount;
    private int  maxCount;

    public StatusChecker(int count)
    {
        invokeCount  = 0;
        maxCount = count;
    }

    // This method is called by the timer delegate.
    public void CheckStatus(Object stateInfo)
    {
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
        Console.WriteLine("{0} Checking status {1,2}.", 
            DateTime.Now.ToString("h:mm:ss.fff"), 
            (++invokeCount).ToString());

        if(invokeCount == maxCount)
        {
            // Reset the counter and signal Main.
            invokeCount  = 0;
            autoEvent.Set();
        }
    }
}
 
Share this answer
 
v2
That was not a timer with threading. This is a timer with threading:

C#
using System;
using System.ServiceProcess;
using System.Threading;
using System.Timers;

namespace MyNamespace
{
    public partial class Service1:  ServiceBase
    {
        Thread syncThread = null;
        System.Timers.Timer timer1;

        public Service1()
        {
            InitializeComponent();             
        }

        protected override void OnStart(string[] args)
        {
            timer1 = new System.Timers.Timer();
            timer1.Interval = 60000; // 1 min
            timer1.Enabled = true;
            timer1.Elapsed += new ElapsedEventHandler(timer1_Elapsed);
            timer1.Start();
        }
        protected override void OnStop()
        {
            syncThread.Abort();
            timer1.Stop();
        }
        protected void timer1_Elapsed(object sender, ElapsedEventArgs e)
        {
            syncThread = new Thread(new ThreadStart(doStuffInMyOwnThread));
            syncThread.Start();
        }
        protected void doStuffInMyOwnThread()
        {
            // whatever you put here, it will
            // run for each timer interval that elapses
            // in a separate thread, and each thread will
            // end when the processing in this function ends            
        } 
    }
}
 
Share this answer
 
Comments
Patrice T 13-Dec-16 20:28pm    
Just 5 years too late.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900