본문 바로가기
개발언어/.NET

C# delegate 사용법 - 사례2

by 공장장코난 2019. 1. 15.

WinForm 환경에서 C#으로 개발중 스레드 혹은 이벤트 콜백 내에서 화면의 Control에 접근하게 될 경우 

아래와 같은 오류가 발생한다.(*'크로스 스레드 작업이 잘못되었습니다.')

SerialPort 선언 후 DataReceived 이벤트 핸들러를 등록, SeriaPort 이벤트 핸들러 내에서 스캐너로부터 받은 데이터를 ListBox에 Add 시키는 과정이다. 직접 연결해서 접근할 수 없으니 우회해서 Add 시켜줄 수 밖에 없다. 여기서도 function pointer 즉 delegate가 이용된다.

SerialPort objBarcodeScanner = new SerialPort();

objBarcodeScanner.PortName = "COM4";

objBarcodeScanner.BaudRate = 115200;

objBarcodeScanner.StopBits = System.IO.Ports.StopBits.One;

objBarcodeScanner.DataBits = 8;

objBarcodeScanner.Parity = System.IO.Ports.Parity.None;

objBarcodeScanner.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnSerialPort_DataReceived); //<-SerialPort 이벤트 핸들러

objBarcodeScanner.Open();

...

문제의 코드

private void OnSerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

{
    this.lbxScanList.Items.Add(objBarcodeScanner.ReadExisting()); <-- 문제의 코드
}


수정코드

//delegate event 선언
public delegate void BarcodeScanEventHandler(string inReadData);

BarcodeScanEventHandler scanEventHandler = new BarcodeScanEventHandler(RefreshScanDataProc);

...

//function 선언

private void RefreshScanDataProc(string inReadData)
{
    this.lbxScanList.Items.Add(inReadData);
}

private void OnSerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)

{
    this.Invoke(scanEventHandler, new object[] { strRecvData }); <-- 변경된 코드
}

예전에 한거 다 까먹는중...ㅡㅡ;