2012-07-19 3 views
1

TEKTRONIX 020-2924-XX DPO DEMO 2 보드에서 USB를 통해 메시지를 전송하는 USB2-F-7x02 CANBus adapter 에 대해 Microsoft Visual C# 2010 Express에 코드를 작성하고 있습니다.스레드에서 DataGridView 채우기

아래 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은 그렇지 않습니다. 불행히도, 나는 정적 키워드를 제거 할 수 없다. 호출 함수에 구문 오류가 생길 수 있기 때문이다. 또한, 은 디자인 양식 파일에서 초기화시 구문 오류가 발생하므로 dataGridView1을 정적으로 선언 할 수 없습니다.

두 번째 옵션은 파일을 열고 쓰는 것입니다. 그러나 StreamWriter 객체를 선언하고 사용할 때 정적으로 호출되는 콜백 관련 오류가 으로 나타납니다. 그래서 콘솔로 출력하고 추적을 사용하여 파일로 리디렉션하기로 결정했습니다 (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

사실 콜백 메서드를 비 정적으로 만들 수 있습니다. 위임자는 "이 전화"를하기 위해 썽크로 마샬링되는 것을 담당합니다. 트릭은 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

관련 문제