首先,感谢小沈阳同学提供的启发。
关于Timer.stop方法,网上介绍的一直是C/S架构下的方法。最近做的程序中,有一个是定时播放声音的,例子如下:
[DllImport("winmm")]
public static extern bool PlaySound(string szSound, IntPtr hMod, int i);//注册声音的事件
protected void Button3_Click(object sender, EventArgs e)//播放声音的按钮。
{
PlaySound(@Server.MapPath("/wav/ding.wav"), IntPtr.Zero, 1);
}
protected void Button5_Click(object sender, EventArgs e)//停止
{
t.Stop();
}
protected void Button6_Click(object sender, EventArgs e)//循环播放
{
t = new System.Timers.Timer(Convert.ToDouble(1000));
t.Elapsed += new System.Timers.ElapsedEventHandler(Button3_Click);
t.AutoReset = true;
t.Enabled = true;
}
调试时发现想让t.stop()没起作用,Timer对象根本就停不下来。Button5_Click里t.Stop()只要一执行就发生“未将对象引用到实例”的错误,而且发现t对象竟然为空。我Timer对象是在外部建立的,不可能访问不到。而且网上说都可以这样停,可是在这里却不可能实现。在Button6_Click里设断点也检测不到Timer对象。在网上搜了竟然有人说这个东西在B/S架构里竟然不好停,因为它不像C/S里对象不会随页面刷新而重建,而在B/S里当按钮提交了,页面生存周期结束了就捕捉不到了。非要写Application才可以,而且Application还很耗资源。
不甘心就这样放弃,问题是Timer对象建立了就根本停不下来了,除非关闭.net端口。连关闭页面都不行,照响不误。
最后,在小沈阳同学的提议下试了在Button3_Click里捕捉Timer对象,没想到t很快就找到了,看来关键是System.Timers.ElapsedEventHandler所响应的事件里,t在那里生存和循环。
解决办法有了。如果要停下Timer对象,在Button3_Click里加个判断就可以了:
public static string stopp = "";//stopp对象一定要是静态的,否则页面刷新将导致变量值丢失。
protected void Button3_Click(object sender, EventArgs e)
{
PlaySound(@Server.MapPath("/wav/ding.wav"), IntPtr.Zero, 1);
if (stopp == "stopd")//关闭并释放资源
{
t1.Stop();
t1.Close();
t1.Dispose();
t1 = null;
}
}
protected void Button5_Click(object sender, EventArgs e)
{
stopp = "stopd";//其实,要Timer对象停,只要做这个stopp变量(一定要静态公共变量),并给它赋停下来的值就可以了,这个可以自己定义。而且,在任何页面,任何地方,只要赋值,它就会停下。
}
protected void Button6_Click(object sender, EventArgs e)
{
stopp = "xunhuan";
t = new System.Timers.Timer(Convert.ToDouble(1000));
t.Elapsed += new System.Timers.ElapsedEventHandler(Button3_Click);
t.AutoReset = true;
t.Enabled = true;
}
没想到这么简单就实现了,Timer对象的停止。看来,在编程中的注意观察,和对类的了解十分重要。