none
有關System.Threading.Timer RRS feed

  • 問題

  • 不好意思,最近在研究使用c#,利用socket寫小型的多人連線遊戲,先說明開發環境
    作業系統版本- Windows Server 2003
    開發工具版本-Visual Studio 2010
    開發環境-Windows Form


    各位高手好:

    開始比賽時候時間會開始倒數,當時間到的時候,則停止比賽。

    因此使用System.Threading.Timer來倒數,參考MSDN的範例(http://msdn.microsoft.com/zh-tw/library/system.threading.timer.aspx),用MessageBox.Show可以顯示3秒、2秒、1秒,

    但需要再label上面顯示倒數時間,所以改成label,label是用委派去撰寫(如下),但是改成label就無法使用了。會顯示錯誤訊息

    "需要物件參考才能使用非靜態、方法或屬性"

    "關鍵字this不能用於靜態屬性、靜態方法或靜態欄位初始設定式"


    將static 拿掉之後,會顯示錯誤訊息"無法存取外部型別xxx.Form1的非靜態成員(透過巢狀型
    別"xxx.Form1.StatusChecker")"


    public static void Show_label33(string string_text)
                {
                    mydel a = Show_label33;
                    object[] obj;
                    obj = new object[1];
                    obj[0] = string_text;
                    if (label33.InvokeRequired) 
                        this.Invoke(a, obj);
                    else 
                        this.label33.Text = (string)obj[0];
                }



    想請問各位高手要如何解決呢>"<
    不好意思,才疏學淺,麻煩各位高手解惑,謝謝。

    2012年2月24日 上午 10:27

解答

  • Hi,

    建議您先了解static的功用

    以你這個method來看~要改變某個物件的label~不應該用static

    你應該把static拿掉~然後將造成"無法存取外部型別xxx.Form1的非靜態成員(透過巢狀型
    別"xxx.Form1.StatusChecker")"的程式給秀出來

    據我從有限的資訊下去推測~這問題應該是你類別與物件之間分不太清楚造成的

    xxx內應該要有個Form1型態的物件~應該要對那物件去操作~而非對類別下去操作


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    • 已標示為解答 alice770920 2012年2月26日 下午 05:23
    2012年2月24日 下午 01:00
  • Sorry,請問您為何不用 Timer 類別 呢?

    System.Timers.Timer.Timer

    或是從工具列上拉一個Timer來用!

    會不會比較Easy呢?


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2012年2月25日 上午 02:50
    • 已標示為解答 alice770920 2012年2月26日 下午 05:23
    2012年2月25日 上午 12:11
  • Hi,

    如果現在你是私下學習~想要學好程式

    建議將前面大家提到的觀念測底釐清

    以你的程式來說~錯誤觀念很多~這樣最後兜出的程式就算能動也是很可怕的

    像是StatusChecker內你的Show_label33怎麼控制label的?!

    StatusChecker類別內根本沒有Show_label33方法

    甚至是沒有Form1物件實體

    另外你的AutoResetEvent看來是用來卡Timer的

    讓Timer跑完期望的次數後才往下跑

    然後再把Timer給釋放

    這怎麼看都不像是必要的

    建議你先行參考下面的小範例~思考一下我們說的問題點

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication8
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                StatusChecker statusChecker = new StatusChecker(3);
                System.Threading.Timer stateTimer = new System.Threading.Timer(new TimerCallback(statusChecker.CheckStatus));          
                stateTimer.Change(0, 1000);
            }
        }
    
        class StatusChecker
        {
            private int invokeCount;
            private int maxCount;
    
            public StatusChecker(int count)
            {
                invokeCount = 0;
                maxCount = count;
            }
    
            public void CheckStatus(Object stateInfo)
            {
                Console.WriteLine("public void CheckStatus(Object stateInfo)");
            }
        }
    }


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    2012年2月25日 上午 02:18
  • alice您好,    嗯,您說的沒有錯! System.Windows.Form.Timer的確比較heavy!

    如果您使用System.Threading.Timer已解了您的問題,那就用那個是比較好的選擇!

    每個物件都有它的適用性,就看系統的規劃如何適當的配置它們!

    System.Windows.Forms.Timer与System.Timers.Timer的区别


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 alice770920 2012年2月27日 上午 11:40
    2012年2月26日 下午 05:44

所有回覆

  • Hi,

    建議您先了解static的功用

    以你這個method來看~要改變某個物件的label~不應該用static

    你應該把static拿掉~然後將造成"無法存取外部型別xxx.Form1的非靜態成員(透過巢狀型
    別"xxx.Form1.StatusChecker")"的程式給秀出來

    據我從有限的資訊下去推測~這問題應該是你類別與物件之間分不太清楚造成的

    xxx內應該要有個Form1型態的物件~應該要對那物件去操作~而非對類別下去操作


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/

    • 已標示為解答 alice770920 2012年2月26日 下午 05:23
    2012年2月24日 下午 01:00
  •  static方法無法使用未宣告成static的方法, 屬性, 或變數

    2012年2月24日 下午 03:00
  • 建議你閱讀 MSDN 文件庫的 [靜態類別和靜態類別成員 (C# 程式設計手冊)] 與 [類別 (C# 程式設計手冊)]

    靜態成員和執行個體成員的角色定義與差異很基本, 也很重要, 務必弄清楚.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2012年2月24日 下午 03:17
    版主
  • AutoResetEvent autoEvent = new AutoResetEvent(false);
    StatusChecker statusChecker = new StatusChecker(3);

    TimerCallback tcb = statusChecker.CheckStatus;
    System.Threading.Timer stateTimer = new System.Threading.Timer(tcb, autoEvent, 1000, 1000);
    autoEvent.WaitOne(3000, false);
    stateTimer.Change(0, 1000);
    stateTimer.Dispose();

    //===============================================

        class StatusChecker
            {
                private int invokeCount;
                private int maxCount;

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

                public void CheckStatus(Object stateInfo)
                {
                    AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
                    if (invokeCount == maxCount)
                    {
                        invokeCount = 0;
                        autoEvent.Set();
                    }
                    else
                        Show_label33((++invokeCount).ToString() + "秒");
                }
            }

    顯示錯誤"無法存取外部型別xxx.Form1的非靜態成員(透過巢狀型別"xxx.Form1.StatusChecker")"
    Show_label33((++invokeCount).ToString() + "秒");

    謝謝您。

                        
    2012年2月24日 下午 04:13
  • 謝謝您的建議。
    2012年2月24日 下午 04:15
  • Sorry,請問您為何不用 Timer 類別 呢?

    System.Timers.Timer.Timer

    或是從工具列上拉一個Timer來用!

    會不會比較Easy呢?


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2012年2月25日 上午 02:50
    • 已標示為解答 alice770920 2012年2月26日 下午 05:23
    2012年2月25日 上午 12:11
  • Hi,

    如果現在你是私下學習~想要學好程式

    建議將前面大家提到的觀念測底釐清

    以你的程式來說~錯誤觀念很多~這樣最後兜出的程式就算能動也是很可怕的

    像是StatusChecker內你的Show_label33怎麼控制label的?!

    StatusChecker類別內根本沒有Show_label33方法

    甚至是沒有Form1物件實體

    另外你的AutoResetEvent看來是用來卡Timer的

    讓Timer跑完期望的次數後才往下跑

    然後再把Timer給釋放

    這怎麼看都不像是必要的

    建議你先行參考下面的小範例~思考一下我們說的問題點

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication8
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                StatusChecker statusChecker = new StatusChecker(3);
                System.Threading.Timer stateTimer = new System.Threading.Timer(new TimerCallback(statusChecker.CheckStatus));          
                stateTimer.Change(0, 1000);
            }
        }
    
        class StatusChecker
        {
            private int invokeCount;
            private int maxCount;
    
            public StatusChecker(int count)
            {
                invokeCount = 0;
                maxCount = count;
            }
    
            public void CheckStatus(Object stateInfo)
            {
                Console.WriteLine("public void CheckStatus(Object stateInfo)");
            }
        }
    }


    謙卑學習,持之以恆,才能不斷的Level Up http://www.dotblogs.com.tw/larrynung/


    2012年2月25日 上午 02:18
  • 亂馬客 您好:

    因為之前爬文有人說
    "原先建立 System.Windows.Form.Timer 的執行緒引發 Tick 事件,如果執行緒忙碌中,Tick 事件引發的時間點就會延遲,所以常見到網友反應 System.Windows.Form.Timer 不夠準時,其實不是計時器不準時,是執行緒忙碌造成 Tick 事件無法即時觸發。"

    因為我是socket撰寫此程式,每個client靠一個server傳值, 怕多執行緒的情況下,Timer會不夠準時,且查資料說System.Threading.Timer是輕量執行緒的計時器,所以才使用System.Threading.Timer。

    那不知您建議使用哪種Timer 撰寫呢?謝謝。

    2012年2月26日 下午 05:05
  • 蹂躪 您好:

    謝謝您的建議,讓我受益良多,我會先去好好釐清觀念,謝謝您。
    2012年2月26日 下午 05:22
  • alice您好,    嗯,您說的沒有錯! System.Windows.Form.Timer的確比較heavy!

    如果您使用System.Threading.Timer已解了您的問題,那就用那個是比較好的選擇!

    每個物件都有它的適用性,就看系統的規劃如何適當的配置它們!

    System.Windows.Forms.Timer与System.Timers.Timer的区别


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    • 已標示為解答 alice770920 2012年2月27日 上午 11:40
    2012年2月26日 下午 05:44
  • 亂馬客 您好:

    目前還在測試中,先以System.Threading.Timer使用看看,慢慢去try,謝謝您。

    2012年2月27日 上午 11:40
  • 您好,提供您其他網友推薦我看的有關Timer的文章,非常推薦您去看哦

    billchung有寫一篇介紹^^

    http://www.dotblogs.com.tw/billchung/archive/2009/04/18/8044.aspx

    2012年3月2日 上午 05:52