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,可以节省不少时间
看了楼主的代码 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.循环里面尽量少声明变量 很浪费资源 可以在循环外面声明循环里面可以清空再赋值
看了楼主的代码 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.循环里面尽量少声明变量 很浪费资源 可以在循环外面声明循环里面可以清空再赋值
这么大的量啊
看得过来吗?
SubTag = temp.Tag.ToString().Substring(5);
不要用Tag
不要用Substring
最好能精确定位到要操作的控件
最好连控件都不要,DrawString
我的winform是在使用时候由用户来设计的,微软的设计器模式,界面上有什么控件,控件在哪个位置,大小,外观,都是由用户自己来决定的
不用tag和Substring,那怎么才能更好的在系统运行时候去判断当前这个控件应该由哪里读入数据呢?
确实看不过来
你说的办法我也想过,这里顺便提出一个问题BeginInvoke 的机制,是每次调用,哪怕调用的函数是个空函数,UI线程也要切换一次,但是界面不重绘
还是必须在调用的函数内执行控件赋值,界面才会重绘?
只是还不知道怎么做。。才能使 ShowData()固定时间运行一次
已经明白了。你的办法是以前做C的时候用过的,C#还有TIMER控件可以实现类似的功能
多谢了
在我不断加大数据量的时候
出现 ”当前线程处于堆栈溢出状态,因此无法计算表达式的值。“
有时候出现在 form.dll上,有时候出现在其他dll上。咋解决啊,加了 GC.Collect() 都没用。
{
temp.Text = Dat[i].ToString();//写入数据
}
这样的代码很让人费解,你直接计算控件最终要写入的值,只写入一次不好吗?
用12楼的思路比较好,在ShowData里把数据保存到内存,然后用一个timer定期刷新界面就行了,要注意lockSubTag = temp.Tag.ToString().Substring(5);
if (Dat[0] == Convert.ToDouble(SubTag))
这里也应该能优化的,可以建一个类,分别保存tag的前5个字符,和后面的double数据,再把这样的对象赋给控件的tag,可以节省不少时间
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.循环里面尽量少声明变量 很浪费资源 可以在循环外面声明循环里面可以清空再赋值
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.循环里面尽量少声明变量 很浪费资源 可以在循环外面声明循环里面可以清空再赋值
没有死循环的,确实没有考虑到界面刷新的执行时间,因为以前都没有做过带界面的软件,以为界面效率应该和底层效率差不多呢。。现在已经是做定时刷新了,并且每次只写入数组的最后一位值,有一定好转。回头试试用time控件的定时
顶10楼。