我的程序用于监视几十个下位机的数据,按照要求主界面上要根据每个下位机的数据显示不同的图片,例如报警就显示红色图片。所以我做了个usercontrol,上面就是一个label一个picturebox一个tooltip,其中tooltip是用来当鼠标移动到图片上时显示几个重要的下位机数据。
然后在主界面动态加载几十个这种usercontrol,然后每秒钟根据当前数据刷新界面。现在的问题是,每更新一次界面要花2秒甚至3秒时间,系统时间显示总是每次蹦几秒,鼠标移动显示tooltip也有明显卡顿。
求助高手。
我这么写的
private void main(object sender, EventArgs e)
{
Thread thread_1s=new Thread(new ThreadStart(UI_callback));
thread_1s.IsBackground=true;
thread_1s.Start();
}
private void UI_callback()
{
while(true)
{
this.BeginInvoke(new EventHandler(RefreshUI),null);
Thread.Sleep(1000);
}
private void RefreshUI(object sender, EventArgs e)
{
toolStripStatusLabelTime.Text=DateTime.Now.Tostring();
//根据当前数据刷新界面,例如if(alarms[Station.Id].Count>0){pictureBox1.Image=imageList1.Images[3];}
}
------解决思路----------------------
为什么要显示 红色 图片 ,可以用一个label 让后改变它的Background。
蹦几秒 是因为 你加了 Thread.Sleep(1000);
------解决思路----------------------
是每个UserControl执行一个main(object sender, EventArgs e)吗?
如果是,有几十个UserControl就会有几十个UI_callback线程,它们将互相竞争。
建议你只在主窗口用一个定时器,定时刷新各个UserControl。
定时器用System.Windows.Forms.Timer,不需要另外BeginInvoke.
------解决思路----------------------
以下例子用了40个UserControl,每秒刷新。
建议你新建一个WinForm项目,拷贝例子代码,替换掉Form1类,即可编译运行。
public partial class Form1 : Form
{
public Form1()
{
FlowLayoutPanel panel = new FlowLayoutPanel() { Padding = new Padding(8), Dock = DockStyle.Fill };
for (int i = 0; i < 40; i++)
{
myUserControlList.Add(new MyUserControl());
panel.Controls.AddRange(myUserControlList.ToArray());
}
this.Controls.Add(panel);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
foreach (MyUserControl myControl in myUserControlList)
{
MyData data = new MyData() { Description = DateTime.Now.Second.ToString(), Status = random.Next(3) };
myControl.Update(data);
}
}
Random random = new Random();
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { Interval = 1000 };
List<MyUserControl> myUserControlList = new List<MyUserControl>();
class MyData
{
public string Description { get; set; }
public int Status { get; set; }
}
class MyUserControl : UserControl
{
public MyUserControl()
{
this.Controls.AddRange(new Control[] { label, pictureBox });
this.Size = new Size(60, 30);
}
public void Update(MyData data)
{
label.Text = data.Description;
pictureBox.Image = images[data.Status % images.Length];
}
Label label = new Label() { Width = 30 };
PictureBox pictureBox = new PictureBox() { Location = new Point(30, 0), };
static Image[] images = new Image[] { SystemIcons.Warning.ToBitmap(), SystemIcons.Question.ToBitmap(), SystemIcons.Information.ToBitmap() };
}
}
------解决思路----------------------
上面的回帖我没看,或许我的回复有重复,特此先说明一下。
看了一眼你的代码,它实在是太“坑爹”了啊。你的代码
Thread thread_1s=new Thread(new ThreadStart(UI_callback));
thread_1s.IsBackground=true;
thread_1s.Start();
}
private void UI_callback()
{
while(true)
{
this.BeginInvoke(new EventHandler(RefreshUI),null);
Thread.Sleep(1000);
}
这里,你弄一个线程在那里“玩儿cpu”,让它循环着(本身线程上下文相关数据结构要占用资源,它还抢占其它线程的CPU调度资源),目的是干什么呢?只是为了向主线程注册一个 RefreshUI 方法么?并且你的 RefreshUI 方法也还都是在主线程排队执行的。
.net的Timer比你自己写的线程死循环要高效得多得多。就算是你使用最低级的Timer(.net至少共有3种或者4种Timer),使用它的代码比你写的线程代码更清晰。你的这种程序根本用不着什么线程的。就像刚学编程的人一样学会拖一个Timer控件到设计画面上,就比你的代码还要好。
------解决思路----------------------
几十字不卡才怪。这个没有解决办法。你网上搜一下,出现这个问题的很多。换一种显示方式吧。