WinForm中访问OPC变量提示‘当前上下文不存在’问题求助
问题描述
使用TitaniumAS开发了一款连接OPC服务器并进行数据读写的程序,控制台环境下运行正常。改为Windows Form应用后,按钮点击事件中无法访问相关方法与变量,报错:The name 'ascon1' does not exist in the current context。
原代码
using TitaniumAS.Opc.Client.Common; using TitaniumAS.Opc.Client.Da; using TitaniumAS.Opc.Client.Da.Browsing; using System.Threading; using System.Threading.Channels; namespace OPCtests { public partial class Form1 : Form { public Form1() { TitaniumAS.Opc.Client.Bootstrap.Initialize(); Uri url = UrlBuilder.Build("Kepware.KEPServerEX.V6"); using (var server = new OpcDaServer(url)) { server.Connect(); OpcDaGroup group = server.AddGroup("MyGroup"); group.IsActive = true; Ascon ascon1 = new Ascon(); ascon1.ALM = ReadX("Channel1.Ascon1.AsconS"); void WriteX(String Link, String Ascon) { var definition1 = new OpcDaItemDefinition { ItemId = Link, IsActive = true }; OpcDaItemDefinition[] definitions = { definition1 }; OpcDaItemResult[] results = group.AddItems(definitions); OpcDaItem tag = group.Items.FirstOrDefault(i => i.ItemId == Link); OpcDaItem[] items = { tag }; object[] Values = { Ascon }; HRESULT[] Results = group.Write(items, Values); } string ReadX(String Link) { var definition1 = new OpcDaItemDefinition { ItemId = Link, IsActive = true }; OpcDaItemDefinition[] definitions = { definition1 }; OpcDaItemResult[] results = group.AddItems(definitions); OpcDaItemValue[] values = group.Read(group.Items, OpcDaDataSource.Device); return Convert.ToString(values[0].Value); } } InitializeComponent(); } void Read_Click(object sender, EventArgs e) { textBox1.Text = ascon1.ALM; } } }
解决建议
- 修正变量作用域:原代码中
ascon1、server、group以及ReadX/WriteX方法都定义在构造函数的using代码块内部,属于局部成员,外部事件无法访问。需要将这些成员提升为Form类的字段:- 在Form类顶部添加类级字段:
private OpcDaServer _server; private OpcDaGroup _group; private Ascon _ascon1; - 移除构造函数中的
using块(server需要保持连接状态,不能在构造函数结束后被自动释放),改为在Form关闭时手动释放资源。
- 在Form类顶部添加类级字段:
- 迁移方法到类级别:将
ReadX和WriteX从构造函数内部移到Form类中,作为成员方法,确保事件处理程序能调用。 - 调整初始化顺序:把
InitializeComponent();放在构造函数最开始,保证WinForm控件先初始化完成,再执行OPC连接逻辑。
修改后示例代码
using TitaniumAS.Opc.Client.Common; using TitaniumAS.Opc.Client.Da; using TitaniumAS.Opc.Client.Da.Browsing; using System.Threading; using System.Threading.Channels; namespace OPCtests { public partial class Form1 : Form { private OpcDaServer _server; private OpcDaGroup _group; private Ascon _ascon1; public Form1() { InitializeComponent(); InitializeOpcConnection(); } private void InitializeOpcConnection() { TitaniumAS.Opc.Client.Bootstrap.Initialize(); Uri url = UrlBuilder.Build("Kepware.KEPServerEX.V6"); _server = new OpcDaServer(url); _server.Connect(); _group = _server.AddGroup("MyGroup"); _group.IsActive = true; _ascon1 = new Ascon(); _ascon1.ALM = ReadX("Channel1.Ascon1.AsconS"); } private void WriteX(string link, string asconValue) { var definition1 = new OpcDaItemDefinition { ItemId = link, IsActive = true }; OpcDaItemDefinition[] definitions = { definition1 }; OpcDaItemResult[] results = _group.AddItems(definitions); OpcDaItem tag = _group.Items.FirstOrDefault(i => i.ItemId == link); if (tag == null) return; OpcDaItem[] items = { tag }; object[] values = { asconValue }; HRESULT[] writeResults = _group.Write(items, values); } private string ReadX(string link) { var definition1 = new OpcDaItemDefinition { ItemId = link, IsActive = true }; OpcDaItemDefinition[] definitions = { definition1 }; OpcDaItemResult[] results = _group.AddItems(definitions); OpcDaItemValue[] values = _group.Read(_group.Items, OpcDaDataSource.Device); return values.Length > 0 ? Convert.ToString(values[0].Value) : string.Empty; } private void Read_Click(object sender, EventArgs e) { textBox1.Text = _ascon1.ALM; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { _group?.Dispose(); if (_server != null && _server.IsConnected) { _server.Disconnect(); } _server?.Dispose(); } } }
内容的提问来源于stack exchange,提问作者Seyl
相关产品推荐
相关产品推荐

