老师好,我想要的结果是当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 ........... lasalid 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#

解决方案 »

  1.   

       把这个   Lasal32.CB_RLADD_FUNCTYPE methptr = new Lasal32.CB_RLADD_FUNCTYPE(RefListCallBack);
    作为类成员变量,而不是局部变量
    试试
      

  2.   

    封送拆收器保证在平台调用期间委托对象不被回收。
    如果你调用的是EnumChildWindows这样的函数,它要直到枚举完成后才会返回,那么整个枚举期间都属于“平台调用期间”,封送拆收器保证在此期间委托对象不被回收。
    而如果是SetWindowLong这样的函数,它一设置完回调函数就返回,之后封送拆收器就不保证委托对象的存在了。程序需要自己通过某种方法保证委托不被回收,比如保留引用。