2012-07-19 77 views
1

我正在Microsoft Visual C#2010 Express中编写USB2-F-7x02 CANBus adapter 的代码,该代码通过USB从TEKTRONIX 020-2924-XX DPO DEMO 2板传输消息。从线程填充DataGridView

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

我考虑过很多可能性。

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

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

Trace

但是,程序将不得不通过该文件解析并在线程启动后立即将其输出到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; 
    } 
} 

回答

1

你实际上可以使你的回调方法是非静态的。代表负责与thunk进行编组,以进行“此呼叫”。诀窍是你不能在Form的构造函数之外初始化该委托。原因在于除了Ctor以外,没有“this”。这样声明:

private EASYSYNC.CallbackDelegate del; 

然后在构造函数初始化:

del = new EASYSYNC.CallbackDelegate(callback); 

确保您通过“删除”,而不是“回调”当你调用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 
    } 
} 
+0

谢谢你这个工作! – EmbedThis 2012-07-20 18:21:21