簡體   English   中英

c#在計時器停止后停止eventhandler

[英]c# stop eventhandler after timer stops

為什么即使在我停止計時器后,我的事件處理程序也永遠不會停止調用? 我的代碼有問題嗎? 請幫忙!

我把我的整個代碼包括在里面,如果你們能幫我一些幫助請:)

private void Form1_Load(object sender, EventArgs e)
    {
        //Start system
        axInRFIDCtrl1.SelectReaderFeig();
        axInRFIDCtrl1.FEInit();
        short sResult = axInRFIDCtrl1.FEOpen();
        //MessageBox.Show(sResult.ToString());

        //Start timer1
        System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
        timer1.Interval = 1000;
        timer1.Tick += new EventHandler(timer1_Tick);
        timer1.Enabled = true;
        timer1.Start();

        Console.ReadLine();
    }

    public void timer1_Tick(object sender, EventArgs e)
    {
        //Get ID
        string strTagIds = string.Empty;
        int iState = 0;

        axInRFIDCtrl1.FESelect(ref strTagIds, ref iState);

        string[] strTagID = strTagIds.Split(new char[] { '|' });
        string strTag = strTagID[0];
        textBox1.Text = strTag;

        //Connection to datebase
        string c1 = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Project.mdb";
        OleDbConnection con = new OleDbConnection(c1);

        //Bind button
        string txt = textBox1.Text;

        string strOleDbConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Project.mdb";
        string strSqlStatement = string.Empty;
        strSqlStatement = "SELECT * FROM jiahe WHERE [Tag ID] = '" + txt + "'";
        OleDbConnection objConnection = new OleDbConnection(strOleDbConnectionString);
        OleDbDataAdapter objAdapter = new OleDbDataAdapter(strSqlStatement, objConnection);
        DataSet ds = new DataSet();
        objAdapter.Fill(ds);

        DataTable dt = ds.Tables[0];
        dataGridView1.DataSource = dt.DefaultView;

        if (dt.Rows.Count == 1)
        {
            string strLine = string.Empty;
            string strUser = string.Empty;

            foreach (DataRow dr in dt.Rows)
            {
                string strTags = dr["Tag ID"].ToString();
                strUser = dr["User"].ToString();
                string strAge = dr["Age"].ToString();
                string strPhoneNumber = dr["Phone Number"].ToString();

                // prepare command string
                string selectString = @"SELECT Status FROM jiahe where [Tag ID] = '" + textBox1.Text + "'";

                // 1. Instantiate a new command with command text only
                OleDbCommand cmd = new OleDbCommand(selectString, objConnection);

                // 2. Set the Connection property
                cmd.Connection.Open();

                // 3. Call ExecuteScalar to send command
                string str = cmd.ExecuteScalar().ToString();

                cmd.Connection.Close();

                foreach (DataRow datarow in dt.Rows)
                {
                    //string strName = string.Empty;
                    strName = datarow["User"].ToString();

                    if (str.Length == 2 || str.Length == 0)
                    {
                        // prepare command string
                        string updateString = @"update jiahe set Status = 'OUT' where [Tag ID] = '" + textBox1.Text + "'";

                        // 1. Instantiate a new command with command text only
                        OleDbCommand cmd1 = new OleDbCommand(updateString, objConnection);

                        // 2. Set the Connection property
                        cmd1.Connection.Open();

                        // 3. Call ExecuteNonQuery to send command
                        str = cmd1.ExecuteNonQuery().ToString();
                        cmd1.Connection.Close();

                        //write text file to outgoing spool
                        //TextWriter tw = new StreamWriter(@"C:\cygwin\var\spool\sms\outgoing\sms.txt");

                        TextWriter tw = new StreamWriter(@"C:\\Test.txt");
                        {
                            tw.WriteLine("To: 6592786618\n");
                            tw.WriteLine("\n");
                            tw.WriteLine("\n" + strName + @" has just left at " + DateTime.Now);
                            tw.Close();
                        }

                        MessageBox.Show(strName + " has left the house.");

                        //Start timer2
                        System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer();
                        timer2.Interval = 1000 * 60 * 30; //30 mins interval
                        timer2.Tick += new EventHandler(timer2_Tick);
                        timer2.Enabled = true;
                        timer2.Start();

                        //Log to listbox
                        // Set the selection mode to multiple and extended.
                        listBox1.SelectionMode = SelectionMode.MultiExtended;
                        listBox1.BeginUpdate();
                        listBox1.Items.Add(DateTime.Now + " - " + strName + " > OUT");
                        listBox1.EndUpdate();

                        //Log event to log file
                        string cs = "Minder+Finder Event Log";
                        EventLog elog = new EventLog();

                        if (!EventLog.SourceExists(cs))
                        {
                            EventLog.CreateEventSource(cs, cs);
                        }

                        elog.Source = cs;
                        elog.EnableRaisingEvents = true;
                        elog.WriteEntry(DateTime.Now + " - " + strName + " > OUT");
                    }
                    else
                    {
                        // prepare command string
                        string updateString = @"update jiahe set Status = 'IN' where [Tag ID] = '" + textBox1.Text + "'";

                        // 1. Instantiate a new command with command text only
                        OleDbCommand cmd1 = new OleDbCommand(updateString, objConnection);

                        // 2. Set the Connection property
                        cmd1.Connection.Open();

                        // 3. Call ExecuteNonQuery to send command
                        str = cmd1.ExecuteNonQuery().ToString();
                        cmd1.Connection.Close();

                        //write text to outgoing spool
                        TextWriter tw = new StreamWriter(@"C:\\Test.txt");
                        //using (TextWriter tw = File.CreateText("C:\cygwin\var\spool\sms\outgoing\Test.txt"));
                        {
                            tw.WriteLine("To: 6592786618\n");
                            tw.WriteLine("\n");
                            tw.WriteLine("\n" + strName + @" has just returned home at " + DateTime.Now);
                            tw.Close();
                        }
                        MessageBox.Show(strName + " has returned home.");

                        //Stop timer2
                        timer2.Tick -= timer2_Tick;
                        timer2.Enabled = false;
                        timer2.Stop();

                        //Log to listbox
                        // Set the selection mode to multiple and extended.
                        listBox1.SelectionMode = SelectionMode.MultiExtended;
                        listBox1.BeginUpdate();
                        listBox1.Items.Add(DateTime.Now + " - " + strName + " > IN");
                        listBox1.EndUpdate();

                        //Log event to log file
                        string cs = "Minder+Finder Event Log";
                        EventLog elog = new EventLog();

                        if (!EventLog.SourceExists(cs))
                        {
                            EventLog.CreateEventSource(cs, cs);
                        }

                        elog.Source = cs;
                        elog.EnableRaisingEvents = true;
                        elog.WriteEntry(DateTime.Now + " - " + strName + " > IN");

                    }
                }
            }
        }
        else
        {
            timer1.Enabled = false;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form2 = new Form2();
        form2.ShowDialog();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        Form3 form3 = new Form3();
        form3.ShowDialog();
    }

    public void timer2_Tick(object sender, EventArgs e)
    {
        MessageBox.Show(strName + " has left");

        //write text file to outgoing spool
        //TextWriter tw = new StreamWriter(@"C:\cygwin\var\spool\sms\outgoing\sms.txt");
        TextWriter tw = new StreamWriter(@"C:\\Test1.txt");
        {
            tw.WriteLine("To: 6592786618\n");
            tw.WriteLine("\n");
            tw.WriteLine("\n" + strName + @" has just left at " + DateTime.Now);
            tw.Close();
        }
    }

如果你停止計時器(通過調用Stop()或設置Enabled = false ),它將不會再次觸發。 從未見過停止計時器調用事件處理程序的情況。 如果在禁用計時器后仍然調用事件處理程序,則其他一些代碼正在調用它,或者某些東西正在重新啟用計時器。

另請注意,如果事件處理程序當前正在執行,則停止計時器不會中止事件。 它也不會阻止任何未決事件。 雖然這不應該是System.Windows.Forms.Timer的問題,因為它的事件處理程序總是在GUI線程上執行。

如果我是你,我會仔細檢查代碼並查看啟用或禁用計時器的所有位置。 我懷疑你會發現你的代碼中有一些東西會重新啟用計時器。

看到您發布的代碼后編輯:

可能問題是你的計時器事件處理程序中有以下內容:

System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer();
// code that initializes and enables timer

這會創建一個本地timer2變量,它與你在表單范圍內的timer2不同(我假設,因為你暗示代碼編譯,你在一個單獨的范圍內引用timer2 )。 您最終創建了一個新計時器,但禁用計時器的代碼引用了表單范圍timer2 所以正在發生的是你正在創建許多不同的計時器,並且每個計時器最終都會調用相同的事件處理程序。

我希望你在事件處理程序中調用MessageBox.Show只是為了調試目的。 你不想把它們留在那里,因為它們阻止了UI線程並且會阻止額外的計時器滴答,直到它們被解雇。

如果timer2是一個實例變量,那么問題是你正在創建一個名為timer2的局部變量並啟動它。 然后,您將停止成員變量timer2,而不是本地作用域timer2。 本地范圍timer2將繼續觸發,直到垃圾收集器繞過它來處理它。

我很確定timer2是一個實例變量,否則對它的其他引用將無法編譯。 還要注意,因為你在循環中創建了timer2,你可能正在創建它們中的一大堆,並且所有這些都快樂地開火,直到垃圾收集器將它們排除在他們的痛苦之外。

編輯:這是一個在Form中使用的一個相當簡單的例子。

http://www.java2s.com/Code/CSharp/GUI-Windows-Form/GUIandtimer.htm

如果您只是將計時器組件放到表單設計中,那么將在InitializeComponents方法中為您編寫初始化,如本例所示。 除此之外,我無法忍受更多。 我認為你嘗試使用計時器的方式存在一些結構性問題。 所有的啟動和停止,特別是對於循環中的timer2似乎會導致你很麻煩和頭痛。

您的停止代碼會更好:

//Stop timer2
timer2.Stop();
timer2.Tick -= timer2_Tick;

至於你真正的問題......我們需要看到你的其余代碼來幫助你。

這樣編寫的代碼永遠不會觸發定時器,因為它會在時間流逝之前(以三種不同的方式)被阻止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM