c # stop обработчик событий после остановки таймера - PullRequest
1 голос
/ 17 ноября 2011

Почему мой обработчик событий не прекращает звонить даже после того, как я остановил свой таймер?Что-то не так с моим кодом?Пожалуйста, помогите!

Я включил весь свой код внутрь, если вы, ребята, могли бы помочь мне, пожалуйста:)

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();
        }
    }

Ответы [ 4 ]

2 голосов
/ 17 ноября 2011

Если timer2 является переменной экземпляра, то проблема в том, что вы создаете локальную переменную, также называемую timer2, и запускаете ее.Затем вы останавливаете переменную-член timer2, а не локальную область timer2.Таймер локальной области видимости будет продолжать срабатывать до тех пор, пока сборщик мусора не захочет его утилизировать.

Я почти уверен, что timer2 - это переменная экземпляра, иначе другие ссылки на него не скомпилируются.Также обратите внимание, что, поскольку вы создаете timer2 внутри цикла, вы, вероятно, создаете множество из них, и все они счастливо увольняются, пока сборщик мусора не избавит их от страданий.

РЕДАКТИРОВАТЬ:Вот довольно простой пример использования формы.

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

Если вы просто перетаскиваете компоненты таймера на свой дизайн формы, то инициализация записывается для вас в методе InitializeComponents, как в этом примере.Кроме этого, я не могу помочь намного больше.Я думаю, что есть некоторые структурные проблемы в том, как вы пытаетесь использовать таймер.Кажется, что все запуск и остановка, особенно с помощью timer2 в цикле for, приведут к большим проблемам и головной боли.

2 голосов
/ 17 ноября 2011

Если вы остановите таймер (вызвав 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 в обработчике событий только для целей отладки. Вы не хотите оставлять их там, потому что они блокируют поток пользовательского интерфейса и будут препятствовать дополнительным тикам таймера, пока они не будут отклонены.

1 голос
/ 17 ноября 2011

Ваш код остановки будет лучше:

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

Что касается вашего реального вопроса ... нам нужно увидеть остальную часть вашего кода, чтобы помочь вам.

0 голосов
/ 17 ноября 2011

Этот код, как написано, никогда не запускает таймер, потому что он предотвращается (тремя различными способами) до истечения времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...