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;
}
}
그러나 이것은 결코 작업을 중단하지 않으며 나는 이유를 알지 못합니다!
이 문제를 어떻게 해결해야합니까? 아니면 내가 원하는 것을 달성하기위한 더 좋은 방법이 있습니까? 미리 감사드립니다!
DispatcherPriority.SystemIdle을 사용하고 다른 옵션을 사용하지 않은 이유는 무엇입니까? – pix
try_port.open()이 실행되기 전에 Action의 Update_ComboBox가 완료되었는지 확인 했습니까? 그렇다면 코드를 디버깅 했습니까? 코드를 테스트하지 않고서도 오류가 작업 내에서 UI를 업데이트하는 것과 아무런 관련이 없다고 생각됩니다. – ooorndtski
예 코드를 디버깅했습니다. 그리고 ui 코드를 루프에 넣으면됩니다. 작업을 완료하는 데 오랜 시간이 걸리는 것을 제외하고는 정상적으로 작동합니다. – user8595258