如何让两个后台工作者使用相同的串口?

时间:2016-12-22 12:18:01

标签: c# multithreading serial-port locking backgroundworker

我有一个通过串口与微控制器通信的应用程序,我需要在后台工作器中定期检查控制器的状态,并允许用户异步地(通过用户界面)与控制器交互,通过发送命令和接收响应(也在后台工作者中)。

这是我的串行通信课程:

using System;
using System.IO.Ports;
using System.Timers;

namespace GUI_WPF
{
static class SerialCommunication
{
    static SerialPort serialPort = new SerialPort();
    static int readWriteTimeout = 2000; // [ms]
    static string endOfString = "" + char.MinValue;

    static object _commandLock = new object();

    public static void SerialPortInit(string portName)
    {
        if (serialPort.IsOpen == true)
        {
            serialPort.Close();
        }

        serialPort.PortName = portName;
        serialPort.BaudRate = 115200;
        serialPort.Parity = Parity.None;
        serialPort.DataBits = 8;
        serialPort.StopBits = StopBits.One;
        serialPort.Handshake = Handshake.None;

        // Set the read/write timeouts [ms]
        serialPort.ReadTimeout = readWriteTimeout;
        serialPort.WriteTimeout = readWriteTimeout;

        serialPort.Open();
    }

    public static string SerialRead()
    {
        try
        {
            serialPort.DiscardInBuffer();
            return serialPort.ReadTo(endOfString);
        }
        catch (Exception ex)
        {
            throw new Exception("SerialCommunication.SerialRead(): " + ex.Message);
        }
    }

    public static string SerialRead(int numberOfReads)
    {
        try
        { // The controller sends terminator char after each value transmitted, so using this method we can read multiple values
            serialPort.DiscardInBuffer();
            string response = "";
            for (int i = 0; i < numberOfReads; i++)
            {
                response += serialPort.ReadTo(endOfString) + " ";
            }
            return response;
        }
        catch (Exception ex)
        {
            throw new Exception("SerialCommunication.SerialRead(): " + ex.Message);
        }
    }

    public static void SerialWrite(string text)
    {
        try
        {
            serialPort.DiscardOutBuffer();
            serialPort.Write(text);
        }
        catch (Exception ex)
        {
            throw new Exception("SerialCommunication.SerialWrite(): " + ex.Message);
        }
    }

    public static string SerialWriteAndRead(string text)
    {
        lock (_commandLock) // If command is called from a thread while is executed on another thread, the lock forces the calling thread to wait
        {
            SerialWrite(text);
            return SerialRead();
        }
    }

    public static string SerialWriteAndRead(string text, int numberOfReads)
    {
        lock (_commandLock) // If command is called from a thread while is executed on another thread, the lock forces the calling thread to wait
        { // The controller sends terminator char after each value transmitted, so using this method we can read multiple values
            SerialWrite(text);
            return SerialRead(numberOfReads);
        }
    }

    public static string SerialRead(int numberOfReads, int timeoutMillisecods)
    {
        serialPort.ReadTimeout = timeoutMillisecods;
        string response = SerialRead(numberOfReads);
        serialPort.ReadTimeout = readWriteTimeout;
        return response;
    }

    public static string[] GetSerialPorts()
    {
        return SerialPort.GetPortNames();
    }

    public static void ClosePort()
    {
        try
        {
            if (serialPort.IsOpen == true)
            {
                serialPort.Close();
            }
        }
        catch { }
    }
}
}

在某种情况下,监视器每2秒询问一次控制器。有时(大多数情况下)当用户从GUI发出等待响应的命令时,会出现以下异常:由于线程退出或应用程序请求,I / O操作已中止。

为什么&#34;锁定()&#34;方法不起作用?怎么办呢?

0 个答案:

没有答案