日期:2014-05-18  浏览次数:21087 次

C#多线程的问题!比较复杂!望大神指点!
情况是这样的,这是代码
C# code

         port.DataReceived += comm_DataReceived;//注册接受串口数据的事件,意思是只要串口有数据来,就触发响应函数

        }
        void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            MethodInvoker dataremi = new MethodInvoker(updatemainlable);//异步形式,为了能访问父进程的控件
            IAsyncResult iar=BeginInvoke(dataremi);//开始
            Thread.sleep(1000); //没这句话,UI界面停止更新。疑问之处。
            if (iar.IsCompleted)//判断串口数据接受的线程有没有执行好,好了就做下面的
            {
                outoffcontrol();//看看采集来的数值是否超标
                savedata();//将采集来的数据存入数据库
            }
        }


功能实现的非常好!没有问题。但是当我想要看看整个程序的性能时。问题就来了。这程序在不断的创建新的线程,几分钟就能创建700多个线程。
经过排查,发现只要在 comm_DataReceived 函数里出现Thread.sleep(1000); ,那么就会出现不停创建新线程的情况。
但是没有Thread.sleep(1000); 这条语句的话,程序就一直循环在updatemainlable函数的开头到Application.DoEvents();这条语句。造成该线程无法进行下去,界面的数据无法更新。

所以想问问大神们,这是为什么?为什么在这样的函数里面不能有Thread.sleep这句话?

------解决方案--------------------
BeginInvoke本身是用线程池来实现的,如果你用sleep,那么当前的处理线程就会被阻塞,那么当下一次接收到数据时,由于线程池中的上个线程被阻塞,那么当前就没有可以使用的线程,那么线程池就会再创建新的线程,以至于几分钟就能创建700多个线程。
“但是没有Thread.sleep(1000); 这条语句的话,程序就一直循环在updatemainlable函数的开头到Application.DoEvents();这条语句。造成该线程无法进行下去,界面的数据无法更新。”
别用sleep这种方式,给BeginInvoke方法中传递 callBack