首頁 > 軟體

C#中的timer與執行緒使用

2022-08-12 14:04:58

C#的timer與執行緒使用

卡頓怎麼處理,多執行緒。多執行緒比timer好讀。看看timer和執行緒的關係。

timer有3種

1.winform 下的timer。就是拖控制元件到UI上的那個timer.   

原始檔在這個路徑下C:WindowsMicrosoft.NETFramework64v4.0.30319

namespace System.Windows.Forms
{
    // 摘要:    實現按使用者定義的時間間隔引發事件的計時器。 此計時器最宜用於 Windows 表單應用程式中,並且必須在視窗中     使用。
    [DefaultEvent("Tick")]
    [DefaultProperty("Interval")][SRDescriptionAttribute("DescriptionTimer")][ToolboxItemFilter("System.Windows.Forms")]
    public class Timer : Component
}

啟動timer程式碼如下:  

[SRCategory("CatBehavior")]
    [DefaultValue(false)]
    [SRDescription("TimerEnabledDescr")]
    public virtual bool Enabled
    {
        get
        {
            if (this.timerWindow == null)
            {
                return this.enabled;
            }
            return this.timerWindow.IsTimerRunning;
        }
        set
        {
            lock (this.syncObj)
            {
                if (this.enabled != value)
                {
                    this.enabled = value;
                    if (!base.DesignMode)
                    {
                        if (value)
                        {
                            if (this.timerWindow == null)
                            {
                                this.timerWindow = new TimerNativeWindow(this);
                            }
                            this.timerRoot = GCHandle.Alloc(this);
                            this.timerWindow.StartTimer(this.interval);
                        }
                        else
                        {
                            if (this.timerWindow != null)
                            {
                                this.timerWindow.StopTimer();
                            }
                            if (this.timerRoot.IsAllocated)
                            {
                                this.timerRoot.Free();
                            }
                        }
                    }
                }
            }
        }
    }

最終呼叫了this.timerWindow.StartTimer(this.interval); 原始碼如下。

可見,最終呼叫的是系統的timer?系統是有定時器的。Ucos上,就有32個定時器,當然也可以開執行緒。

他們是不同的概念。windows 也差不多吧。這些定時器應該與CPU有關。

public void StartTimer(int interval)
    {
        if (this._timerID == 0 && !this._stoppingTimer && this.EnsureHandle())
        {
            this._timerID = (int)SafeNativeMethods.SetTimer(new HandleRef(this, base.Handle), TimerNativeWindow.TimerID++, interval, IntPtr.Zero);
        }
    }

2.  public sealed class Timer : MarshalByRefObject, IDisposable   System.Threading.Timer

    public Timer(TimerCallback callback)
    {
        int dueTime = -1;
        int period = -1;
        StackCrawlMark stackCrawlMark = StackCrawlMark.LookForMyCaller;
        this.TimerSetup(callback, this, (uint)dueTime, (uint)period, ref stackCrawlMark);
    }
 
    [SecurityCritical]
    private void TimerSetup(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark)
    {
        if (callback == null)
        {
            throw new ArgumentNullException("TimerCallback");
        }
        this.m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period, ref stackMark));
    }
 
    [SecurityCritical]
    internal static void Pause()
    {
        TimerQueue.Instance.Pause();
    }
 
    [SecurityCritical]
    internal static void Resume()
    {
        TimerQueue.Instance.Resume();
    }

這裡是TimerQueue 佇列的操作。既然在Threading 名稱空間下,可能與執行緒有關。他在的dll 是 mscorlib.

3.  System.Timers.Timer,  在system.dll中。  只是對 System.Threading.Timer的封裝。

    [TimersDescription("TimerEnabled")]
    [DefaultValue(false)]
    public bool Enabled
    {
        get
        {
            return this.enabled;
        }
        set
        {
            if (base.DesignMode)
            {
                this.delayedEnable = value;
                this.enabled = value;
            }
            else if (this.initializing)
            {
                this.delayedEnable = value;
            }
            else if (this.enabled != value)
            {
                if (!value)
                {
                    if (this.timer != null)
                    {
                        this.cookie = null;
                        this.timer.Dispose();
                        this.timer = null;
                    }
                    this.enabled = value;
                }
                else
                {
                    this.enabled = value;
                    if (this.timer == null)
                    {
                        if (this.disposed)
                        {
                            throw new ObjectDisposedException(base.GetType().Name);
                        }
                        int num = (int)Math.Ceiling(this.interval);
                        this.cookie = new object();
                        this.timer = new System.Threading.Timer(this.callback, this.cookie, num, this.autoReset ? num : (-1));
                    }
                    else
                    {
                        this.UpdateTimer();
                    }
                }
            }
        }
    }

4.使用:

void Application_Start(object sender, EventArgs e)
    {
        // 在應用程式啟動時執行的程式碼
        if (timer != null)
        {
            timer.Stop();
            timer.Close();
            timer = null;
        }
        int Interval = 3600000;//6 hours 
        timer = new System.Timers.Timer(Interval);//十分鐘  
        timer.Elapsed += SendSMS.Send_ticker;
        timer.Interval = Interval;
        timer.Enabled = true;
        timer.Start();
    }

C#新執行緒延時

開啟一個新執行緒

在這個執行緒中,進行任務排隊。

任務1完成後,等待延時200ms,再執行任務2

 private void Timer1_Tick(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            Task.Run(() =>
            {
            
                this.Invoke( new Action( () => 
                {
                    listBox1.Items.Add("進中斷"+DateTime.Now.ToString() + "rn");
                }));
                //RS485.Set_io(7);//ok
                //RS485.Rest_io(7);//ok
                if (i > 8) i = 0;
                RS485.Set_io(i++);//ok
                this.Invoke(new Action(() =>
                {
                    listBox1.Items.Add("第1次輸出" + DateTime.Now.ToString() + "rn");
                }));
 
 
                Thread.Sleep(200);
                RS485.Rest_io((ushort)(i - 2));//ok                                           
                this.Invoke(new Action(() =>
                {
                    listBox1.Items.Add("第2次輸出" + DateTime.Now.ToString() + "rn");
                }));
 
 
                Thread.Sleep(200);
                //RS485.Read_io_out(0,8);//ok
                RS485.Read_io_in(0, 8);//ok
                this.Invoke(new Action(() =>
                {
                    listBox1.Items.Add("第3次輸出" + DateTime.Now.ToString() + "rn");
                }));
                //RS485.Read_io_Reg(0,4);//
                //RS485.Read_io_Regs(0, 6);//
                Thread.Sleep(200);
            });
        }

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。 


IT145.com E-mail:sddin#qq.com