求解答C#委托已回收
老师好,我想要的结果是当PLC值变化时,上位机c#值会跟着变化,也就是监控。我在委托里面加断点确实可以触发。但是正常运行时会报委托已回收,要保持委托处于活动状态 等。 希望得到老师们的帮助该怎么弄。结果是textbox能反应出PLC值的变化来。跪求解释。using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using OnlineSigmatek;
namespace RefreshListSample
{
/// <summary>
/// Interaktionslogik für Window1.xaml
/// </summary>
public partial class Window1 : Window
{
int iRlb;
Lasal32.SRLVarInfo var1;
Lasal32.SRLVarInfo var2;
uint VarID;
int Data;
public Window1()
{
InitializeComponent();
this.iRlb = 0;
this.var1 = new Lasal32.SRLVarInfo();
this.var2 = new Lasal32.SRLVarInfo();
}
// delegate
public void RefListCallBack(uint dwCallbackData, uint dwAddr, uint dwVarID, int nData)
{
Console.WriteLine("Id=" + dwVarID.ToString() + " Data=" + nData.ToString());
// dwCallbackData ... will be 2345 (user specified)
// dwAddr ........... 易做图lid of changed server
// dwVarID .......... will be 88 or 99 (user specified)
// nData ............ changed value (datasize <= 32bit) or crc32 of changed data (datasize > 32bit)
//... // user has to act on changed value
VarID = dwVarID; //我在这里加了断点
Data = nData;
textBox1.Text = VarID.ToString();
textBox2.Text = Data.ToString();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Lasal32.CB_RLADD_FUNCTYPE methptr = new Lasal32.CB_RLADD_FUNCTYPE(RefListCallBack);
this.iRlb = Lasal32.LslRefreshListCreateExt("TCP:10.10.150.37;ApplID=10", 0, 0, 0, null, methptr, 2345, 10000);
if (this.iRlb != 0)
{
if (Lasal32.LslRefreshListGetVarInfo(this.iRlb, "Obj_Csharptest.ListServer", ref this.var1) == true)
Lasal32.LslRefreshListAdd(this.iRlb, ref this.var1, 88, 100, Lasal32.CpReflist.RF_DYNAMIC); // add entry to refreshlist
if (Lasal32.LslRefreshListGetVarInfo(this.iRlb, "Obj_Csharptest.Position", ref this.var2) == true)
Lasal32.LslRefreshListAdd(this.iRlb, ref this.var2, 99, 100, Lasal32.CpReflist.RF_DYNAMIC); // add entry to refreshlist
// ... add some more if you want
Lasal32.LslRefreshListStart(this.iRlb, Lasal32.CpReflist.RF_DYNAMIC); // start refreshlist
// ... watch outputwindow
}
}
private void button2_Click(object sender, RoutedEventArgs e)
{
if(this.iRlb != 0)
Lasal32.LslRefreshListDestroy(this.iRlb); // destroy refreshlist
}
}
}
c# --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 把这个 Lasal32.CB_RLADD_FUNCTYPE methptr = new Lasal32.CB_RLADD_FUNCTYPE(RefListCallBack);
作为类成员变量,而不是局部变量
试试
--------------------编程问答-------------------- 楼上正解!~方法执行完毕,局部变量已被释放了!~ --------------------编程问答-------------------- 封送拆收器保证在平台调用期间委托对象不被回收。
如果你调用的是EnumChildWindows这样的函数,它要直到枚举完成后才会返回,那么整个枚举期间都属于“平台调用期间”,封送拆收器保证在此期间委托对象不被回收。
而如果是SetWindowLong这样的函数,它一设置完回调函数就返回,之后封送拆收器就不保证委托对象的存在了。程序需要自己通过某种方法保证委托不被回收,比如保留引用。
补充:.NET技术 , C#