为什么即使在我停止计时后,我的事件处理程序也永远不会停止呼叫?我的代码有问题吗?请帮忙!
我已将我的整个代码包含在内,如果你们能帮我一些帮助,请:)
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();
}
}
答案 0 :(得分:2)
如果您停止计时器(通过拨打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线程并且会阻止额外的计时器滴答,直到它们被解雇。
答案 1 :(得分:2)
如果timer2是一个实例变量,那么问题是你正在创建一个名为timer2的局部变量并启动它。然后,您将停止成员变量timer2,而不是本地作用域timer2。本地作用域timer2将继续发射,直到垃圾收集器处理它为止。
我很确定timer2是一个实例变量,否则对它的其他引用将无法编译。还要注意,因为你在循环中创建了timer2,你可能正在创造一大堆它们,所有这些都快乐地开火,直到垃圾收集器将它们从痛苦中解脱出来。
编辑:这是一个在Form中使用的相当简单的示例。
http://www.java2s.com/Code/CSharp/GUI-Windows-Form/GUIandtimer.htm
如果您只是将计时器组件放到表单设计中,那么将在InitializeComponents方法中为您编写初始化,如本例所示。除此之外,我无法忍受更多。我认为你尝试使用计时器的方式存在一些结构性问题。所有的启动和停止,特别是对于循环中的timer2,似乎会给你带来很多麻烦和头痛。
答案 2 :(得分:1)
您的停止代码会更好:
//Stop timer2
timer2.Stop();
timer2.Tick -= timer2_Tick;
至于你真正的问题......我们需要看到你的其余代码来帮助你。
答案 3 :(得分:-1)
这个代码,因为写入永远不会触发计时器,因为它会在时间流逝之前被阻止(以三种不同的方式)。