簡體   English   中英

如何啟動和取消任務?

[英]How to start the task and cancel it?

我想自動檢測SerialPort 因此,我有五個組合框來選擇SerialPort的參數,如下所示:

<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" />

當我單擊btn_Auto_Detect我想將這些組合框的不同參數設置為try_Port並嘗試通過使用try_Port發送數據來連接設備。 問題是此操作可能需要幾分鍾。 因此,這次我可以取消此任務。

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;
        }
    }

但這永遠不會停止任務,我也不知道為什么!

我應該如何解決此問題,或者有什么更好的方法來實現我想要的? 提前致謝!

您需要在循環中檢查IsCancellationRequested屬性。 您可以在任務開始時對其進行一次檢查,然后再也不進行檢查。

我會在進行較慢的操作之前檢查它,如果在進行較慢的一項操作之后,我會立即檢查它。 然后退出您的功能,取消將根據需要進行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM