1

私は現在、シリアルポートを読み取る必要がある C# アプリケーションに取り組んでいます。UI には、ユーザーがクリックしてシリアル ポートからのデータの読み取りを開始および停止できるようにする ON/OFF ボタンがあります。ボタンのオンとオフを連続してクリックすると。例外がスローされました-COM3へのアクセスが拒否されたか、「デバイスが接続されていません」とさえ言われました。上記のような状況を解決できるシリアルポート機能を実装するためのより良い方法を誰かが提案できますか? 私が使用するコードは次のとおりです。

**// Start reading data from serial port**
public override void StartReading(string portname)
{
    try
    {
        int k = int.Parse(portname.Replace("COM", ""));
        if (startThread != null)
        {
            startThread.Abort();
            startThread = null;
        }

        startThread = new Thread(new ThreadStart(delegate
        {
            isActive = true;
            try
            {
                using (SerialPort sp = new SerialPort(portname))
                {
                    if (!isActive)
                    {
                        DisposeBT(sp);
                        return;
                    }
                    sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
                    if (!isActive)
                    {
                        DisposeBT(sp);
                        return;
                    }

                    if (!isActive)
                    {
                        DisposeBT(sp);
                        return;
                    }
                    else
                    {
                        Thread.Sleep(6500);
                        try
                        {
                            if (sp != null && !sp.IsOpen)
                            {
                                sp.Open();
                            }

                        }
                        catch (Exception ex)
                        {
                           Logger.Warn("Failed to open the serial port for HRM once. Try it again.");
                            Logger.Error(ex);
                            ////////////////////// new added below
                            if(sp !=null && sp.IsOpen)
                            {
                                sp.Dispose();
                            }
                            Thread.Sleep(6500);
                            if (IsPortAvailable(k))
                            {
                                try
                                {
                                    if (sp != null && !sp.IsOpen)
                                    {
                                        sp.Open();
                                    }

                                }
                                catch (Exception ex1)
                                {
                                    ////////////////////// new added below
                                    if (sp != null && sp.IsOpen)
                                    {
                                        sp.Dispose();
                                    }
                                    Logger.Warn("Failed to open the serial for HRM twice.");
                                    Logger.Error(ex1);
                                    // return;
                                }
                            }
                        }

                    }
                    while (true)
                    {

                        if (!isActive)
                        {
                            DisposeBT(sp);
                            break;
                        }
                    }
                    if (!isActive)
                    {
                        DisposeBT(sp);
                        return;
                    }
                    DisposeBT(sp);
                }
            }
            catch (Exception ex)
            {
                Logger.Warn("Exception thrown for HRM.");
                Logger.Error(ex);
            }

        }));
        startThread.IsBackground = true;
        startThread.Priority = ThreadPriority.Highest;
        startThread.Start();
    }
    catch (Exception ex)
    {
        Logger.Warn("Failed to start reading for HRM02I3A1 bluetooth device.");
        Logger.Error(ex);
    }
}

// Stop reading data from serial port
public override void StopReading()
{
    try
    {
        isActive = false;
    }
    catch { }
}

// event handler for the serial port to read data from sp.
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (isActive)// && startThread.IsAlive
    {
        SerialPort sp1 = (SerialPort)sender;
        try
        {
            sp1.Read(data, 0, 8);
            decoder.Decode(data);
        }
        catch(Exception ex)
        {
            Logger.Warn("------data received from Serial Port error for HRM-------");
            Logger.Error(ex);
        };
    }   
}
4

2 に答える 2

2

まず、キャンセル イベントを受け入れるバックグラウンド ワーカー スレッドを作成します。

メソッドでは、そのDoWorkようなものを書くことができます

void DoWork{
    // init com port
    while(no body cancelled the background worker){
         // if there any waiting data receive and process it. do not use event handlers
    }
    // close the serial port so you can open it again later.
}

また、バックグラウンド作業をキャンセルしたい場合は簡単です

// send cancel command.
// wait till it is canceled.
于 2013-03-13T18:11:00.993 に答える
0

startThread.Join()への呼び出しの直後に追加してみてくださいstartThread.Abort()

Thread.Abort に関する msdnのドキュメントを参照してください。おそらく、 joinの動作も確認する必要があります。

于 2013-03-13T18:26:05.163 に答える