BeginInvoke 还是要重绘  多线程是可以预防假死的 你用错方向了

解决方案 »

  1.   

    对了,忘了说, ShowData()函数每秒钟触发的次数需要达到至少 2000次/每秒 。。
      

  2.   


    这么大的量啊
    看得过来吗?
    SubTag = temp.Tag.ToString().Substring(5);
    不要用Tag
    不要用Substring
    最好能精确定位到要操作的控件
    最好连控件都不要,DrawString
      

  3.   


    我的winform是在使用时候由用户来设计的,微软的设计器模式,界面上有什么控件,控件在哪个位置,大小,外观,都是由用户自己来决定的
    不用tag和Substring,那怎么才能更好的在系统运行时候去判断当前这个控件应该由哪里读入数据呢?
      

  4.   


    确实看不过来
    你说的办法我也想过,这里顺便提出一个问题BeginInvoke 的机制,是每次调用,哪怕调用的函数是个空函数,UI线程也要切换一次,但是界面不重绘
    还是必须在调用的函数内执行控件赋值,界面才会重绘?
      

  5.   

    现在也准备用这种办法了
    只是还不知道怎么做。。才能使 ShowData()固定时间运行一次
      

  6.   

    最简单的做法,用一个后台运行的显示线程A,数据处理线程B每次处理后计数,计数器溢出或到达阈值就触发一次A,然后A刷新界面,B清空计数器,继续处理数据。。
      

  7.   


    已经明白了。你的办法是以前做C的时候用过的,C#还有TIMER控件可以实现类似的功能
    多谢了
      

  8.   

    又遇到了新问题
    在我不断加大数据量的时候
    出现 ”当前线程处于堆栈溢出状态,因此无法计算表达式的值。“
    有时候出现在 form.dll上,有时候出现在其他dll上。咋解决啊,加了 GC.Collect() 都没用。
      

  9.   

                                for (int i = 1; i < Dat.Length; i = i + 99)
                                {
                                    temp.Text = Dat[i].ToString();//写入数据
                                }
    这样的代码很让人费解,你直接计算控件最终要写入的值,只写入一次不好吗?
    用12楼的思路比较好,在ShowData里把数据保存到内存,然后用一个timer定期刷新界面就行了,要注意lockSubTag = temp.Tag.ToString().Substring(5);
    if (Dat[0] == Convert.ToDouble(SubTag))
    这里也应该能优化的,可以建一个类,分别保存tag的前5个字符,和后面的double数据,再把这样的对象赋给控件的tag,可以节省不少时间
      

  10.   

    看了楼主的代码
    1.像这样大量数据操作时,影响到主线程了,必须开线程。
    2.大量数据操作不要循环嵌套,一层循环都最好不要。----思路问题建议
    1.开线程处理数据。
    2.在执行数据处理的时候关闭界面重绘。可用sendmessage API        [DllImport("user32")]
            private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
            private const int WM_SETREDRAW = 0xB;SendMessage(AddClientContrl.Handle, WM_SETREDRAW, 0, IntPtr.Zero);//禁止该控件重绘
    SendMessage(AddClientContrl.Handle, WM_SETREDRAW, 1, IntPtr.Zero);//开启该控件重绘
    3.数据绑定后再开启重绘 强制重绘一次
    4.处理数据的时候。最好给该数据打好标记。避免循环。控件用tag属性可以存object
    5.循环里面尽量少声明变量   很浪费资源     可以在循环外面声明循环里面可以清空再赋值
      

  11.   

    看了楼主的代码
    1.像这样大量数据操作时,影响到主线程了,必须开线程。
    2.大量数据操作不要循环嵌套,一层循环都最好不要。----思路问题建议
    1.开线程处理数据。
    2.在执行数据处理的时候关闭界面重绘。可用sendmessage API        [DllImport("user32")]
            private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
            private const int WM_SETREDRAW = 0xB;SendMessage(AddClientContrl.Handle, WM_SETREDRAW, 0, IntPtr.Zero);//禁止该控件重绘
    SendMessage(AddClientContrl.Handle, WM_SETREDRAW, 1, IntPtr.Zero);//开启该控件重绘
    3.数据绑定后再开启重绘 强制重绘一次
    4.处理数据的时候。最好给该数据打好标记。避免循环。控件用tag属性可以存object
    5.循环里面尽量少声明变量   很浪费资源     可以在循环外面声明循环里面可以清空再赋值
      

  12.   


    没有死循环的,确实没有考虑到界面刷新的执行时间,因为以前都没有做过带界面的软件,以为界面效率应该和底层效率差不多呢。。现在已经是做定时刷新了,并且每次只写入数组的最后一位值,有一定好转。回头试试用time控件的定时
      

  13.   

    timer定时,数据如数据库做个缓冲后再读出。
      

  14.   

    wawd74520的说法是完胜的。
    顶10楼。