2012-10-09 3 views
0

CompactFramework에서 GPRS 연결을 확인하기 위해 스레드에서 작업하고 있습니다.스레드에서 실행중인 serialPort.DataReceived가 작동하지 않습니다.

스레드의 아이디어는 간단합니다. 프로그램이 연결되어 있지 않으면 연결 코드 (이 코드는 오류가 있음)를 실행하지만 연결이 정상이면 60 초 후에 다시 다시 검사합니다. 에.

이제 연결 코드를 중점적으로 살펴 보겠습니다. 다음 코드는 연결되었는지 여부를 확인한 후 연결되지 않은 경우 DataReceive 이벤트를 구독합니다.

void initFormText() 
{ 
    if (isThereConnect()) //true if it is connected 
    { 
     //enable timer to recheck if it's connected 
    } 
    else //it isn't connected 
    { 

     serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived); 
     if (serialPort1.IsOpen) 
     { 
      serialPort1.Close(); 
     } 
     serialPort1.Open(); 

     timerStep.Enabled = true; 
    }  
} 

는 이제 데이터를 확인하고 timerStep에 따라 시험 할 때, 변수를 설정하고 몇 가지 단계를 구성하는 serialPort1_DataReceived에 문제가 온다.

문제는 DataReceived 이벤트 발생는 것은 내가 잘 작동 스레드 외부에서 다음 코드를 실행하면, 모든 작업을 수행하고 아무튼 스레드에서 연결, 하지만을 할 것입니다 일하지 마라. 나는 이것을 약간의 MessageBox을 추가하는 것을 시험해 본다. 그리고 나는 DataReceive 안에 결코 나타나지 않는다는 것을 깨닫는다.

void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 
{ 
    byte[] data = new byte[1024]; 
    int n = serialPort1.Read(data, 0, data.Length); 
    string rec = Encoding.GetEncoding("windows-1252").GetString(data, 0, n); 

    if (string.IsNullOrEmpty(rec)) 
    { 
     return; 
    } 

    if (rec.Contains("AT+CIMI") && rec.Contains("OK")) 
    { 
     MessageBox.Show("serialPort 1"); 
     currState = 1; 
    } 
    else if (rec.Contains("READY")) 
    { 
     MessageBox.Show("serialPort 11"); 
     currState = 1; 
    } 
    else if (rec.Contains("0,1") || rec.Contains("0,5")) 
    { 
     MessageBox.Show("serialPort 2"); 
     currState = 2; 
    } 
} 

그래서 어떤 이유로 serialPort에 아무 것도 수신되지 않아서 그 이유를 알 수 없습니다. 스레드가 아니라 스레드 외부에서 작동한다는 사실은 나를 좌절하게 만듭니다.

감사합니다. 고마워요!

답변

1

예, 이벤트가 시작되기 전에 스레드가 완료된 것 같습니다. 다음과 같은 방법으로 양식을 만들어야합니다.이 코드는 바탕 화면 용 코드이지만 여기에 설치하지 않았으므로 CompactFramework에서 사용할 수있는 것을 시뮬레이트합니다. 첫 번째 Form1은 기본 폼이며 Form2 인 스레드를 시작합니다. Form2에는 버튼이 있고 작동하는 Click EventHandler가 있지만 Application.Run()을 사용하여 Form2를 표시해야합니다. 다음은 샘플 코드입니다.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     Thread thread = new Thread(new ThreadStart(ThreadMethod)); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
    } 
    void ThreadMethod() 
    { 
      Form2 f = new Form2(); 
      Application.Run(f); 
    } 
} 

public partial class Form2 : Form 
{ 
    public Form2() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     MessageBox.Show("Something"); 
    } 
} 

희망 사항은 다음과 같습니다.

+0

고마워요 !!! Application.Run으로 잘 작동합니다! 당신의 도움에 많은 감사드립니다! –

1

이벤트는 이미 serialPort1을 선언 한 동일한 스레드 (UI 스레드라고 가정)에서 실행되어야합니다. 다른 스레드에서 serialPort1_DataReceived 이벤트의 코드를 실행할 수 있습니다. 이 스레드는 serialPort1_DataReceived 이벤트 핸들러에 의해 시작되어야합니다. 문제는 CompactFramework에 ParameterisedThreadStart가 없으므로 수신 된 데이터를 스레드로 효과적으로 전달할 수 없다는 것입니다. 대리자를 사용하여 일부 전역 필드를 설정해야합니다.

+0

내 serialPort는 WinForm에서 선언되고 스레드는 구멍 양식을 실행 중입니다. 그래서 그게 문제가 아니야, 안 그래? –

+0

나는 당신을 올바르게 이해하고 있는가, 당신은 다른 폼에서 istantiated 된 스레드의 WinForm을 가지고 있습니까? –

+0

예, 그렇습니다. 나는 메인 폼을 가지고 있으며,이 GPRS 폼을 실행하는 스레드를 인스턴스화 할 수있다. –

관련 문제