我用C#.NET开发的软件与OMRON的PLC连接,PLC上挂OMRON的触摸屏,
数据库方面使用SQL Server数据库,使用的是存储过程,存储过程稍微有点复杂
C#软件使用一个Timer控件实现同步监控PLC内存数据,读取或者改写PLC的内存,并实现软件界面数据的更新。
但是最终软件的运行速度不理想,软件运行界面会出现几秒的延迟,同时软件读取单个触摸屏上的数据也有相应的延迟。
请问哪位高手能不能帮小弟想下法子,看能不能使软件在运行速度上有所提升。另外,小弟稍微研究了下多线程,但是对于多线程使用的位置和方法不是很明确,有哪位高手能不能指点下。最后提一下,运行软件的服务器是4核CPU,内存1G。迫切期待问题的解决,先谢谢各位了!
数据库方面使用SQL Server数据库,使用的是存储过程,存储过程稍微有点复杂
C#软件使用一个Timer控件实现同步监控PLC内存数据,读取或者改写PLC的内存,并实现软件界面数据的更新。
但是最终软件的运行速度不理想,软件运行界面会出现几秒的延迟,同时软件读取单个触摸屏上的数据也有相应的延迟。
请问哪位高手能不能帮小弟想下法子,看能不能使软件在运行速度上有所提升。另外,小弟稍微研究了下多线程,但是对于多线程使用的位置和方法不是很明确,有哪位高手能不能指点下。最后提一下,运行软件的服务器是4核CPU,内存1G。迫切期待问题的解决,先谢谢各位了!
呵呵,哪怕你的timer间隔时间定在500毫秒,也会有500毫秒的延迟。
而且现在问题是延迟的时间并不是Timer控件的时间间隔那么短,而是达到了几秒的长度
多谢楼上的指点。其实分开来讲,楼上讲的这几点都不慢,但是,由于触摸屏块数比较多,而且每块触摸屏操作完毕都有相应的数据处理要求,
所以整个系统整体来看,就变慢了。我想过用多线程来处理,每个线程单独处理一块屏的数据,但是对于线程分开与PLC进行数据交互时,会不会有数据紊乱的现象发生这是个未知之数,不知道楼上的高手对这方面有什么见解。再次谢谢高手指教!
谢谢,现在总共有15块触摸屏,但是数据总合在一个PLC中,如果多线程在四核CPU的电脑中运行是同时的(微观上的)(这点我现在还不能确信),那么就有可能同时访问PLC,那么PLC响应的数据就会紊乱。系统的存储过程数量也不少,总共程序也不少,因为数据要进行的分析和计算、控制比较多,所以就慢了。
当然,既然软件运行比较慢,那么肯定是有值得优化的地方。再次谢谢!
在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而已,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。再举个简单例子说明下使用方法,比如你在启动一个线程,在线程的方法中想更新窗体中的一个TextBox..
using System.Threading; public delegate void MyInvoke(string str);
private void btnStartThread_Click(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(DoWord));
thread.Start();
}
public void DoWord()
{
MyInvoke mi = new MyInvoke(SetTxt);
BeginInvoke(mi,new object[]{"abc"});
} public void SetTxt(string str)
{
txtReceive.Text += str + System.Environment.NewLine;
}多线程详细请看:.Net中的Thread类:http://hi.baidu.com/grrc/blog/item/6c257beea88768fdb3fb95c7.html
谢谢!听起来好像是这么回事,但是我对多线程在这种情况下的应用还不怎么知道,大虾能不能教小弟以下关于对PLC访问的上锁操作和多线程的应用方法,如果可以的话,最好有个简单的例子,或者发个链接给在下,让我学习学习,以解决燃眉之急!另外,请问一下,照现在这样的分析,如果使用了多线程,而且运行软件的电脑又是4核CPU的,那么是不是可以解决速度问题,让线程在微观上也是同时监控不同的点,从而达到监控不同的屏而不出现串行执行的现象?谢谢了
{
readonly static object _lokcer = new object();
public static PLCDataClass Get(int sectionID)
{
lock(_locker)
{
return InvokePLCApI.Invoke();
}
}public static void Put(int sectionID,PLCDataClass data)
{
lock(_locker)
{
InvokePLCApI.Invoke(...);
}
}
}
Thread[] tds = new Thread[Environment.ProcessorCount * 2];
for(int i = 0;i < tds.Length; i ++)
{
tds[i] = new Thread(delegate(){
PLCAccessHelper.Get();
...
PLCAccessHelperPut();
}
);
tds[i].Startz();
}代码大致是这样,应该能看懂是怎么回事吧
谢谢回复!好像知道怎么回事了,但是有的地方又不是很明白,能不能加点注释啊,特别是这一段:Thread[] tds = new Thread[Environment.ProcessorCount * 2];
for(int i = 0;i < tds.Length; i ++)
{
tds[i] = new Thread(delegate(){
PLCAccessHelper.Get();
...
PLCAccessHelperPut();
}
);
tds[i].Startz();
} 好人做到底嘛,谢谢了!
for(int i = 0;i < tds.Length; i ++)
{
tds[i] = new Thread(delegate(){
PLCAccessHelper.Get();
...
PLCAccessHelperPut();
}
);
tds[i].Startz();
} 这里把委托delegate放在线程里,然后调用
PLCAccessHelper.Get();
...
PLCAccessHelperPut(); 谢谢!
for(int i = 0;i < tds.Length; i ++)
{
tds[i] = new Thread(delegate(){
PLCAccessHelper.Get();
...
PLCAccessHelperPut();
}
);
tds[i].Startz();
} 这里把委托delegate放在线程里,然后调用
PLCAccessHelper.Get();
...
PLCAccessHelperPut(); 解释下,谢谢!
已经很清楚了,谢谢大虾进行回复分析!此帖先到这结帖!谢谢各位,再次谢谢tmxk2002