.NET线程和硬件访问的问题 [英] problem with two .NET threads and hardware access

查看:101
本文介绍了.NET线程和硬件访问的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个应用程序,该应用程序通过FT2232H USB/RS232转换器与设备进行通信.为了进行通讯,我使用了FTDI网站上的FTD2XX_NET.dll库.
我正在使用两个线程:

  • 第一个线程连续从设备读取数据
  • 第二个线程是Windows窗体应用程序的主线程

    当我尝试在接收方的线程运行时将任何数据写入设备时遇到问题.主线程只是挂在ftdiDevice.Write函数上.

    我试图同步两个线程,以便只有一个线程可以同时使用读/写功能,但这没有帮助.

    下面的代码负责通信.请注意,以下函数是FtdiPort类的方法.

    I'm creating an application which communicates with the device via FT2232H USB/RS232 converter. For communication I'm using FTD2XX_NET.dll library from FTDI website.
    I'm using two threads:

  • first thread continuously reads data from the device
  • the second thread is the main thread of the Windows Form Application

    I've got a problem when I'm trying to write any data to the device while the receiver's thread is running. The main thread simply hangs up on ftdiDevice.Write function.

    I tried to synchronize both threads so that only one thread can use Read/Write function at the same time, but it didn't help.

    Below code responsible for the communication. Note that following functions are methods of FtdiPort class.

    
            private void receiverLoop()
            {
                if (this.DataReceivedHandler == null)
                {
                    throw new BackendException("dataReceived delegate is not set");
                }
    
                FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;
                byte[] readBytes = new byte[this.ReadBufferSize];
    
                while (true)
                {
                    lock (FtdiPort.threadLocker)
                    {
                        UInt32 numBytesRead = 0;
    
                        ftStatus = ftdiDevice.Read(readBytes, this.ReadBufferSize, ref numBytesRead);
    
                        if (ftStatus == FTDI.FT_STATUS.FT_OK)
                        {
                            this.DataReceivedHandler(readBytes, numBytesRead);
                        }
                        else
                        {
                            Trace.WriteLine(String.Format("Couldn't read data from ftdi: status {0}", ftStatus));
                            Thread.Sleep(10);
                        }                    
                    }
                    Thread.Sleep(this.RXThreadDelay);
    
                }
            }
    


        public void Write(byte[] data, int length)
        {
            if (this.IsOpened)
            {
                uint i = 0;
    
                lock (FtdiPort.threadLocker)
                {
                    this.ftdiDevice.Write(data, length, ref i);
                }
    
                Thread.Sleep(1);
                if (i != (int)length)
                {
                    throw new BackendException("Couldnt send all data");
                }
            }
            else
            {
                throw new BackendException("Port is closed");
            }
        }
    



    
    static Object threadLocker = new Object();
    

    
            private void startReceiver()
            {
                if (this.DataReceivedHandler == null)
                {
                    return;
                }
                if (this.IsOpened == false)
                {
                    throw new BackendException("Trying to start listening for raw data while disconnected");
                }
                this.receiverThread = new Thread(this.receiverLoop);
                //this.receiverThread.Name = "protocolListener";
                this.receiverThread.IsBackground = true;
                this.receiverThread.Start();
            }
    

    如果我在以下行中注释,则ftdiDevice.Write函数不会挂断:

    The ftdiDevice.Write function doesn't hang up if I comment following line:

    ftStatus = ftdiDevice.Read(readBytes, this.ReadBufferSize, ref numBytesRead);

    推荐答案

    几件事:

    1. 检查您的Read通话是否被阻止.如果是这样,您可能无法在Read阻止等待响应时调用Write.您的API文档可能对此有更多详细信息.

    1. Check to see if your Read call is blocking. If so, you might not be able to call Write while the Read is blocking waiting for a response. Your API documentation may have more details on this.

    某些API即使在同步访问时也无法很好地支持多个线程.如果是这种情况,您可以使用一种设计,在其中将Write命令委托给comm线程.过去使用此模式时,通常会排队某种包含我要编写的信息的Command类,并使用线程化Signal类来允许我的调用"command"方法来阻止或提供某种形式的信息.异步通知.

    Some APIs do not support multiple threads very well, even when synchronizing access. If that's the case here, you can use a design where you delegate your Write commands to your comm thread. When I've used this pattern in the past, I typically queue up some sort of Command class containing the information I wish to write, and either use a threading Signal class to allow my calling 'command' methods to block or provide some sort of asynchronous notification.

    这篇关于.NET线程和硬件访问的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆