1

我正在 Microsoft Visual C# 2010 Express 中为 USB2-F-7x02 CANBus 适配器编写代码,该适配器 通过 USB 从 TEKTRONIX 020-2924-XX DPO DEMO 2 板传输消息。

下面名为 CANSnifferForm.cs 的代码使用与 CANBus API 交互的 GUI。Run_Click 将在用户单击“运行”后打开适配器(canplus_open),然后适配器开始侦听(canplus_Listen)。回调线程 (setReceiveCallBackThread) 然后运行调用调用回调的 setReceiveCallBack。msg 对象包含消息。然后我的问题在于从消息中获取此信息并将其添加到 DataGridView (dataGridView1)。

我考虑了很多可能性。

最明显的是通过编写“this.dataGridView1.Rows.Add(msg.id, msg.len, msg.timestamp);”向 dataGridView 添加行。在回调中。但是,回调实际上是静态的,但 dataGridView1 不是。不幸的是,我不能删除 static 关键字,因为它会导致调用函数出现语法错误。此外,我不能将 dataGridView1 声明为静态,因为这会导致设计表单文件中的初始化出现语法错误。

第二种选择是打开一个文件并写入它。但是,当我声明并使用 StreamWriter 对象时,会导致与静态声明回调有关的错误。因此,我决定输出到控制台并使用跟踪将其重定向到文件(因为 Console.WriteLine 不是静态的)。我在这里找到了关于跟踪的讨论:

追踪

但是,程序必须在线程启动后立即解析该文件并将其输出到 dataGridView。这意味着当线程写入文件时,StreamReader 对象将同时读取文件,这可能导致数据复杂化。这导致程序在我运行它时没有响应。

所以后来我终于考虑声明一个静态数组并在回调中填充它。初始化数组时出现问题。但是,为了使用循环解析它并将其放入 dataGridView,我必须知道数组的大小。当我使用循环解析它时,大小会发生变化。

我开始对此失去耐心。所以我提出我的问题是堆栈溢出。

以下三段代码应包含分析问题所需的所有内容。EASYSYNC.msg 在 EASYSYNC.cs 中声明。我正在做的主要编码是在 CANSnifferForm.cs 中。

// CANSnifferForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;

namespace WindowsFormsApplication1
{

    public partial class CANSnifferForm : Form
    {

        // per the api document. "This is a blocking call and must be called on a separate thread."
        // the code previously after setCallback... was never being reached because the call is   blocking.
        // this calls the setCallbackThread function in another thread so processing can continue.
        Thread setReceiveCallBackThread;
        //static int arrSize = 0;

        int handle, listenReturnValue;
        TextWriter tw = new StreamWriter("dataGridView1.txt");

        public CANSnifferForm()
        {
            InitializeComponent();
        }


        private static void callback(ref EASYSYNC.CANMsg msg)
        {
            // Populate something perhaps??
        }

        EASYSYNC.CallbackDelegate del = new EASYSYNC.CallbackDelegate(callback);

        private void Run_Click(object sender, EventArgs e)
        {

            this.CANSnifferStatusBox.AppendText("CAN closed");
            this.ProcessStatusBox.AppendText("Stopped");
            EASYSYNC.CANMsg msg = new EASYSYNC.CANMsg();
            msg.id = 1;
            msg.timestamp = 2;
            msg.flags = 3;
            msg.len = 4;
            msg.data = 5;
            handle = EASYSYNC.canplus_Open(IntPtr.Zero, "1000", IntPtr.Zero, IntPtr.Zero, 0);

            if (handle < 0)
                this.ErrorBox.AppendText("Error opening CAN");

            this.CANSnifferStatusBox.Clear();
            this.CANSnifferStatusBox.AppendText("CAN open");


            setReceiveCallBackThread = new Thread(() => EASYSYNC.canplus_setReceiveCallBack(handle, callback));
            listenReturnValue = EASYSYNC.canplus_Listen(handle);

            if (listenReturnValue < 0)
            {
                this.ErrorBox.Clear();
                this.ErrorBox.AppendText("Error setting listen mode\n");
                EASYSYNC.canplus_Close(listenReturnValue);
                this.CANSnifferStatusBox.Clear();
                this.CANSnifferStatusBox.AppendText("CAN closed\n");
            }

            this.CANSnifferStatusBox.Clear();
            this.CANSnifferStatusBox.AppendText("CAN Listening\n");

            setReceiveCallBackThread.Start();
            this.ProcessStatusBox.Clear();
            this.ProcessStatusBox.AppendText("Running\n");

            // Insert loop here to populate dataGridView
            // this.dataGridView1.Rows.Add(msg.id, msg.len, msg.timestamp);



        }

      private void Stop_Click(object sender, EventArgs e)
        {
           setReceiveCallBackThread.Abort(); // Stop thread
           this.ProcessStatusBox.Clear();
           this.ProcessStatusBox.AppendText("Stopped");
           EASYSYNC.canplus_Close(listenReturnValue);
           this.CANSnifferStatusBox.Clear();
           this.CANSnifferStatusBox.AppendText("CAN closed");

        }
}


// CANSnifferProgram.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
    static class CANSnifferProgram
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CANSnifferForm());


        }
    }
}

// EASYSYNC.cs

using System;
using System.Runtime.InteropServices;
using System.Text;


internal class EASYSYNC
{
    public const string CAN_BitRate_100K = "100";
    public const string CAN_BitRate_10K = "10";
    public const string CAN_BitRate_125K = "125";
    public const string CAN_BitRate_1M = "1000";
    public const string CAN_BitRate_20K = "20";
    public const string CAN_BitRate_250K = "250";
    public const string CAN_BitRate_500K = "500";
    public const string CAN_BitRate_50K = "50";
    public const string CAN_BitRate_800K = "800";
    public const byte CANMSG_EXTENDED = 0x80;
    public const byte CANMSG_RTR = 0x40;
    public const uint canplus_ACCEPTANCE_CODE_ALL = 0;
    public const uint canplus_ACCEPTANCE_MASK_ALL = uint.MaxValue;
    public const byte CANPLUS_FLAG_BLOCK = 4;
    public const byte CANPLUS_FLAG_NO_LOCAL_SEND = 0x10;
    public const byte CANPLUS_FLAG_QUEUE_REPLACE = 2;
    public const byte CANPLUS_FLAG_SLOW = 8;
    public const byte CANPLUS_FLAG_TIMESTAMP = 1;
    public const byte CANSTATUS_EWARN = 1;
    public const byte CANSTATUS_RXB0OVFL = 0x80;
    public const byte CANSTATUS_RXB1OVFL = 0x40;
    public const byte CANSTATUS_RXBP = 8;
    public const byte CANSTATUS_RXWARN = 2;
    public const byte CANSTATUS_TXBO = 0x20;
    public const byte CANSTATUS_TXBP = 0x10;
    public const byte CANSTATUS_TXWARN = 4;
    public const int ERROR_CANPLUS_COMMAND_SUBSYSTEM = -3;
    public const int ERROR_CANPLUS_FAIL = -1;
    public const int ERROR_CANPLUS_INVALID_HARDWARE = -11;
    public const int ERROR_CANPLUS_INVALID_PARAM = -6;
    public const int ERROR_CANPLUS_MEMORY_ERROR = -8;
    public const int ERROR_CANPLUS_NO_DEVICE = -9;
    public const int ERROR_CANPLUS_NO_MESSAGE = -7;
    public const int ERROR_CANPLUS_NOT_OPEN = -4;
    public const int ERROR_CANPLUS_OK = 1;
    public const int ERROR_CANPLUS_OPEN_SUBSYSTEM = -2;
    public const int ERROR_CANPLUS_TIMEOUT = -10;
    public const int ERROR_CANPLUS_TX_FIFO_FULL = -5;
    public const uint FLUSH_DONTWAIT = 1;
    public const uint FLUSH_EMPTY_INQUEUE = 2;
    public const uint FLUSH_WAIT = 0;

    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Close(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Flush(int h);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_getFirstAdapter(StringBuilder szAdapter, int size);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_getNextAdapter(StringBuilder szAdapter, int size);
    [DllImport("USBCanPlusDllF.dll", EntryPoint="canplus_VersionInfo")]
    public static extern int canplus_getVersionInfo(int handle, StringBuilder verinfo);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Listen(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(IntPtr szID, string szBitrate, IntPtr acceptance_code, IntPtr acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(string szID, string szBitrate, IntPtr acceptance_code, IntPtr acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Open(string szID, string szBitrate, string acceptance_code, string acceptance_mask, uint flags);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Read(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_ReadN(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Reset(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_SetTimeouts(int handle, uint receiveTimeout, uint transmitTimeout);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Status(int handle);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_Write(int handle, ref CANMsg msg);
    [DllImport("USBCanPlusDllF.dll")]
    public static extern int canplus_setReceiveCallBack(int handle, CallbackDelegate callback);

    [UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)]
    public delegate void CallbackDelegate(ref CANMsg msg);

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct CANMsg
    {
        public uint id;
        public uint timestamp;
        public byte flags;
        public byte len;
        public ulong data;
    }

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct CANMsgEx
    {
        public uint id;
        public uint timestamp;
        public byte flags;
        public byte len;
    }
}


// CANSnifferForm.Designer.cs
namespace WindowsFormsApplication1
{
    partial class CANSnifferForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.RunRestart = new System.Windows.Forms.Button();
            this.Stop = new System.Windows.Forms.Button();
            this.Pause = new System.Windows.Forms.Button();
            this.Resume = new System.Windows.Forms.Button();
            this.FilterLength = new System.Windows.Forms.TextBox();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.FilterByID = new System.Windows.Forms.Label();
            this.FilterbyLength = new System.Windows.Forms.Label();
            this.CANSnifferStatus = new System.Windows.Forms.Label();
            this.ErrorBox = new System.Windows.Forms.TextBox();
            this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.ID = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Length = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Data = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.TimeStamp = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.ErrorMessage = new System.Windows.Forms.Label();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.ProcessStatus = new System.Windows.Forms.Label();
            this.ProcessStatusBox = new System.Windows.Forms.TextBox();
            this.CANSnifferStatusBox = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout();
            // 
            // RunRestart
            // 
            this.RunRestart.Location = new System.Drawing.Point(56, 80);
            this.RunRestart.Margin = new System.Windows.Forms.Padding(4);
            this.RunRestart.Name = "RunRestart";
            this.RunRestart.Size = new System.Drawing.Size(125, 39);
            this.RunRestart.TabIndex = 0;
            this.RunRestart.Text = "Run / Restart";
            this.RunRestart.UseVisualStyleBackColor = true;
            this.RunRestart.Click += new System.EventHandler(this.Run_Click);
            // 
            // Stop
            // 
            this.Stop.Location = new System.Drawing.Point(1009, 80);
            this.Stop.Name = "Stop";
            this.Stop.Size = new System.Drawing.Size(154, 39);
            this.Stop.TabIndex = 12;
            this.Stop.Text = "Stop";
            this.Stop.UseVisualStyleBackColor = true;
            this.Stop.Click += new System.EventHandler(this.Stop_Click);
            // 
            // Pause
            // 
            this.Pause.Location = new System.Drawing.Point(232, 80);
            this.Pause.Name = "Pause";
            this.Pause.Size = new System.Drawing.Size(120, 39);
            this.Pause.TabIndex = 13;
            this.Pause.Text = "Pause";
            this.Pause.UseVisualStyleBackColor = true;
            this.Pause.Click += new System.EventHandler(this.Pause_Click);
            // 
            // Resume
            // 
            this.Resume.Location = new System.Drawing.Point(411, 80);
            this.Resume.Name = "Resume";
            this.Resume.Size = new System.Drawing.Size(122, 39);
            this.Resume.TabIndex = 14;
            this.Resume.Text = "Resume";
            this.Resume.UseVisualStyleBackColor = true;
            this.Resume.Click += new System.EventHandler(this.Resume_Click);
            // 
            // FilterLength
            // 
            this.FilterLength.Location = new System.Drawing.Point(620, 88);
            this.FilterLength.Name = "FilterLength";
            this.FilterLength.Size = new System.Drawing.Size(161, 22);
            this.FilterLength.TabIndex = 16;
            this.FilterLength.TextChanged += new System.EventHandler(this.FilterLength_TextChanged);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(850, 88);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(57, 22);
            this.textBox1.TabIndex = 17;
            // 
            // FilterByID
            // 
            this.FilterByID.AutoSize = true;
            this.FilterByID.Location = new System.Drawing.Point(617, 63);
            this.FilterByID.Name = "FilterByID";
            this.FilterByID.Size = new System.Drawing.Size(75, 17);
            this.FilterByID.TabIndex = 18;
            this.FilterByID.Text = "Filter by ID";
            this.FilterByID.Click += new System.EventHandler(this.FilterByID_Click);
            // 
            // FilterbyLength
            // 
            this.FilterbyLength.AutoSize = true;
            this.FilterbyLength.Location = new System.Drawing.Point(847, 63);
            this.FilterbyLength.Name = "FilterbyLength";
            this.FilterbyLength.Size = new System.Drawing.Size(106, 17);
            this.FilterbyLength.TabIndex = 19;
            this.FilterbyLength.Text = "Filter by Length";
            this.FilterbyLength.Click += new System.EventHandler(this.FilterbyLength_Click);
            // 
            // CANSnifferStatus
            // 
            this.CANSnifferStatus.AutoSize = true;
            this.CANSnifferStatus.Location = new System.Drawing.Point(53, 9);
            this.CANSnifferStatus.Name = "CANSnifferStatus";
            this.CANSnifferStatus.Size = new System.Drawing.Size(121, 17);
            this.CANSnifferStatus.TabIndex = 21;
            this.CANSnifferStatus.Text = "CANSniffer Status";
            this.CANSnifferStatus.Click += new System.EventHandler(this.CANSnifferStatus_Click);
            // 
            // ErrorBox
            // 
            this.ErrorBox.BackColor = System.Drawing.SystemColors.Control;
            this.ErrorBox.Location = new System.Drawing.Point(180, 35);
            this.ErrorBox.Name = "ErrorBox";
            this.ErrorBox.Size = new System.Drawing.Size(220, 22);
            this.ErrorBox.TabIndex = 22;
            // 
            // dataGridViewTextBoxColumn1
            // 
            this.dataGridViewTextBoxColumn1.DataPropertyName = "Target";
            this.dataGridViewTextBoxColumn1.HeaderText = "Target";
            this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1";
            this.dataGridViewTextBoxColumn1.ReadOnly = true;
            // 
            // dataGridView1
            // 
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.ID,
            this.Length,
            this.Data,
            this.TimeStamp});
            this.dataGridView1.Location = new System.Drawing.Point(17, 156);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.RowTemplate.Height = 24;
            this.dataGridView1.Size = new System.Drawing.Size(1146, 388);
            this.dataGridView1.TabIndex = 23;
            this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
            // 
            // ID
            // 
            this.ID.HeaderText = "ID";
            this.ID.Name = "ID";
            this.ID.Width = 200;
            // 
            // Length
            // 
            this.Length.HeaderText = "Length";
            this.Length.Name = "Length";
            // 
            // Data
            // 
            this.Data.HeaderText = "Data";
            this.Data.Name = "Data";
            this.Data.Width = 600;
            // 
            // TimeStamp
            // 
            this.TimeStamp.HeaderText = "Time Stamp";
            this.TimeStamp.Name = "TimeStamp";
            this.TimeStamp.Width = 200;
            // 
            // ErrorMessage
            // 
            this.ErrorMessage.AutoSize = true;
            this.ErrorMessage.Location = new System.Drawing.Point(53, 35);
            this.ErrorMessage.Name = "ErrorMessage";
            this.ErrorMessage.Size = new System.Drawing.Size(101, 17);
            this.ErrorMessage.TabIndex = 24;
            this.ErrorMessage.Text = "Error Message";
            // 
            // progressBar1
            // 
            this.progressBar1.Location = new System.Drawing.Point(17, 133);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(69, 17);
            this.progressBar1.TabIndex = 26;
            // 
            // ProcessStatus
            // 
            this.ProcessStatus.AutoSize = true;
            this.ProcessStatus.Location = new System.Drawing.Point(617, 12);
            this.ProcessStatus.Name = "ProcessStatus";
            this.ProcessStatus.Size = new System.Drawing.Size(103, 17);
            this.ProcessStatus.TabIndex = 28;
            this.ProcessStatus.Text = "Process Status";
            // 
            // ProcessStatusBox
            // 
            this.ProcessStatusBox.BackColor = System.Drawing.SystemColors.Menu;
            this.ProcessStatusBox.Location = new System.Drawing.Point(726, 12);
            this.ProcessStatusBox.Name = "ProcessStatusBox";
            this.ProcessStatusBox.Size = new System.Drawing.Size(148, 22);
            this.ProcessStatusBox.TabIndex = 29;
            this.ProcessStatusBox.TextChanged += new System.EventHandler(this.ProcessStatusBox_TextChanged);
            // 
            // CANSnifferStatusBox
            // 
            this.CANSnifferStatusBox.BackColor = System.Drawing.SystemColors.Menu;
            this.CANSnifferStatusBox.Location = new System.Drawing.Point(180, 6);
            this.CANSnifferStatusBox.Name = "CANSnifferStatusBox";
            this.CANSnifferStatusBox.Size = new System.Drawing.Size(163, 22);
            this.CANSnifferStatusBox.TabIndex = 31;
            this.CANSnifferStatusBox.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
            // 
            // CANSnifferForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1357, 533);
            this.Controls.Add(this.CANSnifferStatusBox);
            this.Controls.Add(this.ProcessStatusBox);
            this.Controls.Add(this.ProcessStatus);
            this.Controls.Add(this.progressBar1);
            this.Controls.Add(this.ErrorMessage);
            this.Controls.Add(this.dataGridView1);
            this.Controls.Add(this.ErrorBox);
            this.Controls.Add(this.CANSnifferStatus);
            this.Controls.Add(this.FilterbyLength);
            this.Controls.Add(this.FilterByID);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.FilterLength);
            this.Controls.Add(this.Resume);
            this.Controls.Add(this.Pause);
            this.Controls.Add(this.Stop);
            this.Controls.Add(this.RunRestart);
            this.Margin = new System.Windows.Forms.Padding(4);
            this.Name = "CANSnifferForm";
            this.Text = "CAN Sniffer ";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button RunRestart;
        private System.Windows.Forms.Button Stop;
        private System.Windows.Forms.Button Pause;
        private System.Windows.Forms.Button Resume;
        private System.Windows.Forms.TextBox FilterLength;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label FilterByID;
        private System.Windows.Forms.Label FilterbyLength;
        private System.Windows.Forms.Label CANSnifferStatus;
        private System.Windows.Forms.TextBox ErrorBox;
        private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1;
        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.DataGridViewTextBoxColumn ID;
        private System.Windows.Forms.DataGridViewTextBoxColumn Length;
        private System.Windows.Forms.DataGridViewTextBoxColumn Data;
        private System.Windows.Forms.DataGridViewTextBoxColumn TimeStamp;
        private System.Windows.Forms.Label ErrorMessage;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Label ProcessStatus;
        private System.Windows.Forms.TextBox ProcessStatusBox;
        private System.Windows.Forms.TextBox CANSnifferStatusBox;
    }
}
4

1 回答 1

1

事实上,您可以使您的回调方法成为非静态的。代表负责使用 thunk 进行编组以进行“此调用”。诀窍是您不能在表单的构造函数之外初始化该委托。原因是在ctor之外,没有“this”。像这样声明它:

private EASYSYNC.CallbackDelegate del;

然后在你的构造函数中初始化它:

del = new EASYSYNC.CallbackDelegate(callback);

确保在调用时传递 "del" ,而不是 "c​​allback" EASYSYNC.canplus_setReceiveCallBack(你目前错了)。当它被传递给非托管代码时,最好保留对此委托的引用。当您传递“回调”时,创建了一个委托,但您没有机会保留该引用,我们将在回调中重用该引用。

棘手的一点在于回调方法。您不能从另一个线程将项目添加到 DGV(甚至是绑定容器)。UI 控件不能从创建它们的 UI 线程以外的线程访问。我们可以简单地检查我们是否在另一个线程上执行,如果是,我们将使用 BeginInvoke 重新调用自己,这次是从 UI 线程。

private void callback(ref EASYSYNC.CANMsg msg)
{
    if (InvokeRequired)
        BeginInvoke(del, msg);
    else
    {
        // Now you can add items to the DGV
    }
}
于 2012-07-19T21:57:41.860 回答