日期:2014-05-17  浏览次数:21080 次

Timer.Stop()有效而Timer.Start()无效???求解答
用的是System.Windows.Form命名空间里的计时器
代码如下:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
 {
    timer1.Stop();//为什么Stop之后,无法用start启动??
     timer1.Start();
.........
}

本来计时器是可以正常工作的,一旦接收到数据,执行了timer1.Stop之后,计时器就无法工作了,即使加入了timer1.Start也不行,谁能告诉我这是为什么啊?

如果删除timer1.Stop,计时器是可以正常工作的,这是为哪般啊,难道在接收事件里,timer1.Stop是有效的,但是timer.Start是无效的???

PS:我知道用委托是不会出现问题的,只是想知道为什么这样做,会导致stop有效而start无效

------解决方案--------------------
http://social.msdn.microsoft.com/Forums/ro-RO/vbasiczhchs/thread/1e159d8b-8369-4526-9149-e34d09e5d16d
刚才没理解,需要对你有帮助
------解决方案--------------------
原因就是你错误的使用了它。
winform控件不是线程安全的,对多线程环境下的表现和行为不做保证。或许在某些情况下它可以正常工作;或许在另外一些情况下不能正常工作——一切都听天由命,控件自身不在这些方面做任何特殊处理。
或许在这里不能stop了,在另外一个地方不能start了,在别的什么地方interval又异常了
换句感觉很厉害的话就是:破坏了它的内部状态

打个比方,你把本本往地上一摔,发现不能开机了。原因嘛,反正就是里面什么地方摔坏了,至于究竟哪里的什么摔坏了,那是要拆开检查才知道,每次摔坏的地方不一定一样。
你要做的事,不是去弄清楚,哦,这次硬盘被摔坏了,下次摔的时候要注意点别又把硬盘摔坏了,而是根本就不要去摔它。下次可能你的确是掌握了技巧没把硬盘摔坏但其他地方又摔坏了。或者,你非要摔,就去弄个摔不坏的本本。

非线程安全的函数(类型)占多数,在多线程环境下不加保护的使用都可能出现各种异常状况。应对的方法是,要么以安全的方式使用它们,要么去找对应的线程安全版本。
------解决方案--------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Threading;

namespace WindowsApplication1
{
    public delegate void MyDelegate(string name);//定义委托

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            BtnClick += new MyDelegate(Form1_BtnClick);//注册自定义委托事件
        }
        private event MyDelegate BtnClick;//声明自定义事件

        void Form1_BtnClick(string name)
        {
            Thread th = new Thread(new ThreadStart(startTimer));//用线程执行startTimer函数
            th.Start();
        }

        
        private void Form1_Load(object sender, EventArgs e)//窗体load事件
        {
            BtnClick("...");
        }

        private void timer1_Tick(object sender, EventArgs e)//timer_Tick事件
        {
            Console.WriteLine("111");