C#OPC应用程序相同的代码,但工作方式不同

C#OPC应用程序相同的代码,但工作方式不同,第1张

概述我正在开发一个C#定制OPC客户端,我开始在控制台应用程序中编写快速,一切都按照我想要的方式工作. 然后我决定制作一个视窗体验的Windows窗体应用程序. Windows窗体应用程序只需停止工作,大约一分钟后停止从OPC服务器读取数据.控制台应用程序继续阅读和阅读的位置. 在调试模式下也找不到任何明显的东西. 我绝对在这里抓住稻草,希望有人可以散发光芒. 每个应用程序都使用OPCFoundati 我正在开发一个C#定制OPC客户端,我开始在控制台应用程序中编写快速,一切都按照我想要的方式工作.

然后我决定制作一个视窗体验的Windows窗体应用程序.

windows窗体应用程序只需停止工作,大约一分钟后停止从OPC服务器读取数据.控制台应用程序继续阅读和阅读的位置.

在调试模式下也找不到任何明显的东西.

我绝对在这里抓住稻草,希望有人可以散发光芒.

每个应用程序都使用OPCFoundation提供的.dll文件.

这是控制台应用程序

static voID Main(string[] args)        {            Opc.URL url = new Opc.URL("opcda://localhost/RSlinx OPC Server");            Opc.Da.Server server = null;            OpcCom.Factory fact = new OpcCom.Factory();            server = new Opc.Da.Server(fact,null);            server.Connect(url,new Opc.ConnectData(new System.Net.NetworkCredential()));            // Create a group            Opc.Da.Subscription group;            Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();            groupState.name = "Group";            groupState.Active = true;            group = (Opc.Da.Subscription)server.CreateSubscription(groupState);            // add items to the group.            Opc.Da.Item[] items = new Opc.Da.Item[6];            items[0] = new Opc.Da.Item();            items[0].Itemname = "[UX1]F20:9";            items[1] = new Opc.Da.Item();            items[1].Itemname = "[UX1]F22:30";            items[2] = new Opc.Da.Item();            items[2].Itemname = "[UX1]F22:6";            items[3] = new Opc.Da.Item();            items[3].Itemname = "[UX1]F18:8";            items[4] = new Opc.Da.Item();            items[4].Itemname = "[UX1]F22:32";            items[5] = new Opc.Da.Item();            items[5].Itemname = "[UX1]F22:5";            items = group.AddItems(items);                group.DataChanged += new Opc.Da.DataChangedEventHandler(OnTransactionCompleted);        }        static voID OnTransactionCompleted(object group,object hReq,Opc.Da.ItemValueResult[] items)        {            Console.Writeline("------------------->");            Console.Writeline("DataChanged ...");            for (int i = 0; i < items.GetLength(0); i++)            {                    Console.Writeline("Item DataChange - ItemID: {0}",items[i].Itemname);                    Console.Writeline(" Value: {0,-20}",items[i].Value);                    Console.Writeline(" TimeStamp: {0:00}:{1:00}:{2:00}.{3:000}",items[i].Timestamp.Hour,items[i].Timestamp.Minute,items[i].Timestamp.Second,items[i].Timestamp.Millisecond);            }            Console.Writeline("-------------------<");        }

这是WinForm应用程序

public Form1()    {        InitializeComponent();        _Form1 = this;    }    public static Form1 _Form1;    public voID update(string message)    {        this.richTextBox1.Text = message;    }    private voID Form1_Load(object sender,EventArgs e)    {        readplc();    }static voID readplc()        {                Opc.URL url = new Opc.URL("opcda://localhost/RSlinx OPC Server");            Opc.Da.Server server = null;            OpcCom.Factory fact = new OpcCom.Factory();            server = new Opc.Da.Server(fact,new Opc.ConnectData(new System.Net.NetworkCredential()));            // Create a group            Opc.Da.Subscription group;            Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();            groupState.name = "Group";            groupState.Active = true;            group = (Opc.Da.Subscription)server.CreateSubscription(groupState);            // add items to the group.            Opc.Da.Item[] items = new Opc.Da.Item[6];            items[0] = new Opc.Da.Item();            items[0].Itemname = "[UX1]F20:9";            items[1] = new Opc.Da.Item();            items[1].Itemname = "[UX1]F22:30";            items[2] = new Opc.Da.Item();            items[2].Itemname = "[UX1]F22:6";            items[3] = new Opc.Da.Item();            items[3].Itemname = "[UX1]F18:8";            items[4] = new Opc.Da.Item();            items[4].Itemname = "[UX1]F22:32";            items[5] = new Opc.Da.Item();            items[5].Itemname = "[UX1]F22:5";            items = group.AddItems(items);                group.DataChanged += new Opc.Da.DataChangedEventHandler(OnTransactionCompleted);        }      static voID OnTransactionCompleted(object group,Opc.Da.ItemValueResult[] items)        {            for (int i = 0; i < items.GetLength(0); i++)            {                UIUpdater TEXT = new UIUpdater();                    TEXT.UpdateText(items.GetLength(0).ToString() + " t " + i.ToString() + "Item DataChange - ItemID:" + items[i].Itemname +                       "Value: " + items[i].Value + " TimeStamp: " + items[i].Timestamp.Hour + ":" +                      items[i].Timestamp.Minute + ":" + items[i].Timestamp.Second + ":" + items[i].Timestamp.Millisecond);            }        }

UIUpdate类

class UIUpdater    {       public voID UpdateText(string DATA)        {            Form1._Form1.update(DATA);        }          public class UpdateUI        {            public int updatedRows { get; set; }            public string Custom1 { get; set; }            public string Custom2 { get; set; }            public string Custom3 { get; set; }            public string exception { get; set; }            public plcTextStatus PLCStatus { get; set; }        }

任何问题请问!

解决方法 怀疑,这是一个跨线程问题.问题是你不能从UI线程的任何其他线程更新UI.完成事务的事件实际上在一个单独的线程上被调用,所以它更新了UI.

它工作一段时间,因为它相对容忍的错误,但你可能达到一个点,你是死锁或抛出一个没有被捕获(或报告)的异常.

修复很简单,但是.

在这种方法中:

public voID update(string message){    this.richTextBox1.Text = message;}

将其更改为:

public voID update(string message){    richTextBox1.Invoke(      (MethodInvoker) delegate       {           richTextBox1.Text = message;       });}

这样做是告诉richTextBox1“调用”或运行以下委托(函数)在它自己的线程(也就是UI线程)上.

您应该尽量避免在此代码中使用静态方法和引用.我没有看到你的代码不应该是实例方法而不是静态代码的任何原因.

作为附注,我编写了OPC程序,每秒处理数千个标签和数百个UI更新.你正在做的工作是为小型演示程序,但不会扩大很好.当架构越来越多时,您需要开始批量修改UI更新,因此您不会在更新中重复调用UI线程.

编辑

另一个问题是使用本地引用(例如,对于OPC服务器和订阅),并演示了内存泄漏和僵尸对象.发生了什么是readplc方法超出范围,您已经创建了对内存中保存的对象的引用.由于您无法取消订阅该活动,因此该活动将持续开放.这些变量应该声明在readplc方法的范围之外,所以您可以正确地取消订阅该事件并关闭OPC服务器.否则你正在离开僵尸订阅(看看RSlinx OPC诊断页面,你会看到所有你的订阅坐在那里).

总结

以上是内存溢出为你收集整理的C#OPC应用程序相同的代码,但工作方式不同全部内容,希望文章能够帮你解决C#OPC应用程序相同的代码,但工作方式不同所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1252883.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存