如何将对函数的调用排队

时间:2019-05-13 17:31:54

标签: c# queue thread-safety

我正在通过串行总线与I / O中继板通信。使用字节命令控制和查询该板。我的目标是让backgroundworker定期评估继电器和输入的状态并更新GUI,同时运行“脚本”,该脚本在板上执行一系列动作。

我有两个功能,可以向板发送和接收命令。我的问题是,如果我在使用backgroundworker来更新GUI的同时运行我的“脚本”,则会开始出现读写失败-我想是因为两个进程都在很短的时间内访问了相同的功能。 / p>

static SerialPort USB_PORT;
byte[] SerBuf = new byte[64];
byte usb_found = 0;
byte states = 0;

private void transmit(byte write_bytes)
        {
            try
            {
                if (usb_found == 1) USB_PORT.Write(SerBuf, 0, write_bytes);      // writes specified amount of SerBuf out on COM port
            }
            catch (Exception)
            {
                usb_found = 0;
                MessageBox.Show("write fail");
                return;
            }
        }

private void receive(byte read_bytes)
        {
            byte x;
            for (x = 0; x < read_bytes; x++)       // this will call the read function for the passed number times, 
            {                                      // this way it ensures each byte has been correctly recieved while
                try                                // still using timeouts
                {
                    if (usb_found == 1) USB_PORT.Read(SerBuf, x, 1);     // retrieves 1 byte at a time and places in SerBuf at position x
                }
                catch (Exception)                                       // timeout or other error occured, set lost comms indicator
                {
                    usb_found = 0;
                    MessageBox.Show("read fail");
                    return;
                }
            }
        }

是否有一种方法可以“排队”对这两个函数的所有调用,从而使整个函数在下一个函数开始之前完成?

1 个答案:

答案 0 :(得分:1)

正如@Idle_Mind所建议的那样,我创建了一个对象,然后使用lock语句来防止来自两个不同线程的访问。似乎有效!

static readonly object _Lock = new object();
private void transmit(byte write_bytes)
        {
            lock (_Lock)
            {
                try
                {
                    if (usb_found == 1) USB_PORT.Write(SerBuf, 0, write_bytes);      // writes specified amount of SerBuf out on COM port
                }
                catch (Exception)
                {
                    usb_found = 0;
                    MessageBox.Show("write fail");
                    return;
                }
            }
        }

private void receive(byte read_bytes)
        {
            lock (_Lock)
            {
                byte x;
                for (x = 0; x < read_bytes; x++)       // this will call the read function for the passed number times, 
                {                                      // this way it ensures each byte has been correctly recieved while
                    try                                // still using timeouts
                    {
                        if (usb_found == 1) USB_PORT.Read(SerBuf, x, 1);     // retrieves 1 byte at a time and places in SerBuf at position x
                    }
                    catch (Exception)                                       // timeout or other error occured, set lost comms indicator
                    {
                        usb_found = 0;
                        MessageBox.Show("read fail");
                        return;
                    }
                }
            }
        }