2017-11-09 3 views
0

SerialPort automaticlly를 감지하고 싶습니다.작업을 시작하고 취소하는 방법은 무엇입니까?

<TextBlock Text="BaudRate"/> 
<ComboBox x:Name="comboBox_BaudRate" SelectedIndex="2"> 
    <ComboBoxItem>9600</ComboBoxItem> 
    <ComboBoxItem>14400</ComboBoxItem> 
    <ComboBoxItem>19200</ComboBoxItem> 
    <ComboBoxItem>38400</ComboBoxItem> 
    <ComboBoxItem>56000</ComboBoxItem> 
    <ComboBoxItem>115200</ComboBoxItem> 
</ComboBox> 

<TextBlock Text="DataBit"/> 
<ComboBox x:Name="comboBox_DataBit" SelectedIndex="0" > 
    <ComboBoxItem>8</ComboBoxItem> 
    <ComboBoxItem>7</ComboBoxItem> 
</ComboBox> 

<TextBlock Text="Parity" /> 
<ComboBox x:Name="comboBox_Parity" SelectedIndex="0" > 
    <ComboBoxItem>None</ComboBoxItem> 
    <ComboBoxItem>Odd</ComboBoxItem> 
    <ComboBoxItem>Even</ComboBoxItem> 
</ComboBox> 

<TextBlock Text="StopBit" /> 
<ComboBox x:Name="comboBox_StopBit" SelectedIndex="0" > 
    <ComboBoxItem>1</ComboBoxItem> 
    <ComboBoxItem>2</ComboBoxItem> 
</ComboBox> 

<Button x:Name="btn_Auto_Detect" Click="btn_Find_Click" /> 

나는 내가 try_Port 이러한 콤보 상자의 다른 매개 변수를 설정할 btn_Auto_Detect을 클릭하고 try_Port를 사용하여 전송 데이터에 의해 내 장치를 연결하려고 : 그래서 다음과 같이 SerialPort의 매개 변수를 선택하는 다섯 comboboxs이 . 문제는이 작업을 수행하는 데 몇 분이 걸릴 수 있습니다. 그래서 이번에는이 일을 취소 할 수 있습니다.

public bool cancelFlag = false; 
private void btn_Find_Click(object sender, RoutedEventArgs e) 
{ 
    var tokenSource = new CancellationTokenSource(); 
    var token = tokenSource.Token; 

    if(cancelFlag) 
    { 
     cancelFlag = false; 
     tokenSource.Cancel(); 
     Hint("Searching Canceled!"); 
    } 
    else 
    { 
     cancelFlag = true; 
     Hint("Start Searching..."); 
    } 

    Task.Factory.StartNew(() => 
     { 
      if(!token.IsCancellationRequested) 
      { 
       Matching_Process_Thread(); 
      } 
      else 
      { 
       return; 
      } 
     }, token).ContinueWith(task => 
     { 
      ... 

     }, token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
} 


public static SerialPort try_port = new SerialPort(); 
private void Matching_Process_Thread() 
{ 
    int tryNumber = 0; 
    //Loop searching the portname, baudrate, databit, parity, stopbit 
    for (int i = 0; i < comboBox_Port.Items.Count; i++) 
    { 
     try_port.PortName = comboBox_Port.Items[i].ToString(); 
     for (int j = 0; j < comboBox_BaudRate.Items.Count; j++) 
     { 
      for (int k = 0; k < comboBox_DataBit.Items.Count; k++) 
      { 
       for (int m = 0; m < comboBox_Parity.Items.Count; m++) 
       { 
        for (int n = 0; n < comboBox_StopBit.Items.Count; n++) 
        { 
         //Here I want to update the UI      
         this.Dispatcher.BeginInvoke(
         DispatcherPriority.SystemIdle, new Action<int, int, 
         int, int>(Update_ComboBoxs), j, k, m, n); 

         if(!try_port.isOpen){ try_port.Open(); } 
         ... 
         //if get response, return 
         //else close this try_port.close() and return; 
        } 
       } 
      } 
     } 
    } 

    private void Update_ComboBoxs(int baudrate, int databit, int parity, int stopbit) 
    { 
     this.comboBox_BaudRate.SelectedIndex = baudrate; 
     try_port.BaudRate = int.Parse(comboBox_BaudRate.Text); 

     this.comboBox_DataBit.SelectedIndex = databit; 
     try_port.DataBits = int.Parse(comboBox_DataBit.Text); 

     this.comboBox_Parity.SelectedIndex = parity; 
     switch (parity) 
     { 
      case 0: 
       try_port.Parity = Parity.None; 
       break; 
      case 1: 
       try_port.Parity = Parity.Odd; 
       break; 
      case 2: 
       try_port.Parity = Parity.Even; 
       break; 
      default:break; 
     } 

     this.comboBox_StopBit.SelectedIndex = stopbit; 
     switch (stopbit) 
     { 
      case 0: 
       try_port.StopBits = StopBits.One; 
       break; 
      case 1: 
       try_port.StopBits = StopBits.Two; 
       break; 
      default:break; 
     } 
    } 

그러나 이것은 결코 작업을 중단하지 않으며 나는 이유를 알지 못합니다!

이 문제를 어떻게 해결해야합니까? 아니면 내가 원하는 것을 달성하기위한 더 좋은 방법이 있습니까? 미리 감사드립니다!

+0

DispatcherPriority.SystemIdle을 사용하고 다른 옵션을 사용하지 않은 이유는 무엇입니까? – pix

+0

try_port.open()이 실행되기 전에 Action의 Update_ComboBox가 완료되었는지 확인 했습니까? 그렇다면 코드를 디버깅 했습니까? 코드를 테스트하지 않고서도 오류가 작업 내에서 UI를 업데이트하는 것과 아무런 관련이 없다고 생각됩니다. – ooorndtski

+0

예 코드를 디버깅했습니다. 그리고 ui 코드를 루프에 넣으면됩니다. 작업을 완료하는 데 오랜 시간이 걸리는 것을 제외하고는 정상적으로 작동합니다. – user8595258

답변

0

루프 내부의 IsCancellationRequested 속성을 확인해야합니다. 작업을 시작할 때 한 번 확인한 다음 다시는 확인하지 마십시오.

느린 작업 바로 전에이를 확인하고 둘 이상의 느린 작업이있는 경우 바로 확인하십시오. 그런 다음 기능에서 복귀하면 원하는대로 취소가 작동합니다.

+0

답변 해 주셔서 감사합니다! – user8595258

+0

당신을 진심으로 환영합니다. –

관련 문제