两个 .NET 线程和硬件访问的问题

2024-01-04

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

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

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

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

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

  • 接收者线程

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

    另一种方法是使用 FTDI 的事件通知机制,这样您就不需要阻塞线程来读取数据:

    public FTDISample()
    {
        private AutoResetEvent receivedDataEvent;
        private BackgroundWorker dataReceivedHandler;
        private FTDI ftdi;
    
        public FTDISample(string serialNumber){
            ftdi = new FTDI();
            FTDI.FT_STATUS status = ftdi.OpenBySerialNumber(serialNumber);
            receivedDataEvent = new AutoResetEvent(false);
            status = mFTDI.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, receivedDataEvent);
            dataReceivedHandler = new BackgroundWorker();
            dataReceivedHandler.DoWork += ReadData;
            if (!dataReceivedHandler.IsBusy)
            {
                dataReceivedHandler.RunWorkerAsync();
            }
        }
    
        private void ReadData(object pSender, DoWorkEventArgs pEventArgs)
        {
            UInt32 nrOfBytesAvailable = 0;
            while (true)
            {
                // wait until event is fired
                this.receivedDataEvent.WaitOne();
    
                // try to recieve data now
                FTDI.FT_STATUS status = ftdi.GetRxBytesAvailable(ref nrOfBytesAvailable);
                if (status != FTDI.FT_STATUS.FT_OK)
                {
                    break;
                }
                if (nrOfBytesAvailable > 0)
                {
                    byte[] readData = new byte[nrOfBytesAvailable];
                    UInt32 numBytesRead = 0;
                    status = mFTDI.Read(readData, nrOfBytesAvailable, ref numBytesRead);
    
                    // invoke your own event handler for data received...
                    //InvokeCharacterReceivedEvent(fParsedData);
                }
            }
        }
    
        public bool Write(string data)
        {
            UInt32 numBytesWritten = 0;
            ASCIIEncoding enconding = new ASCIIEncoding();
            byte[] bytes = enconding.GetBytes(data);
            FTDI.FT_STATUS status = ftdi.Write(bytes, bytes.Length, ref numBytesWritten);
            if (status != FTDI.FT_STATUS.FT_OK)
            {
                Debug.WriteLine("FTDI Write Status ERROR: " + status);
                return false;
            }
            if (numBytesWritten < data.Length)
            {
                Debug.WriteLine("FTDI Write Length ERROR: " + status + " length " + data.Length +
                                " written " + numBytesWritten);
                return false;
            }
            return true;
        }
    
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

    两个 .NET 线程和硬件访问的问题 的相关文章

    • JFrame 在连续运行代码时冻结

      我在使用时遇到问题JFrame 它会冻结 连续运行代码 下面是我的代码 点击时btnRun 我调用了该函数MainLoop ActionListener btnRun Click new ActionListener Override pu
    • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

      我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
    • C++0x 初始值设定项列表示例

      我想看看这个现有代码示例如何利用 C 0x 初始化列表功能 示例0 include
    • 静态 OpenCV 库中未定义的引用

      我有一个使用 OpenCV 3 1 的 C 项目 并且使用共享库可以正常工作 但现在我想使用静态库 位于项目目录中的文件夹中 来编译它 因为我希望能够在未安装 OpenCV 的情况下导出它 如果需要还可以编辑和重新编译 这次我重新编译了 O
    • 如何将 Visual-Studio 2010 切换到 c++11

      我是 c 编程新手 我想尝试 c 11 新功能 那么我要问的是如何切换 Visual studio 2010 才能编译 c 11 源代码 你可以参考这个表 VC10 中的 C 0x 核心语言功能 表格 http blogs msdn com
    • 打开位置设置页面或提示用户启用位置

      我一直在绞尽脑汁 徒劳地谷歌搜索 我正在尝试找到一种方法来提示用户通过直接进入设置页面或仅点击屏幕上的 是 来切换位置 我见过的所有代码似乎都不起作用 有人有有效的方法吗 一个详细的例子将不胜感激 谢谢 我对 Xamarin 开发非常陌生
    • PartialView Action 正在调用自身

      我有 MVC 应用程序 它用于从主视图 ProductMaster 将 ProductAreaGrid 列表显示为 PartialView 并且它将在局部视图内将 CreateProductArea 作为 PartialView 我的 Gr
    • C#生成的csv文件通过电子邮件发送嵌入到Lotus Note中电子邮件的底部

      我遇到了一个奇怪的问题 即使用 NET SmtpClient 通过电子邮件发送的 CSV 附件出现在电子邮件底部 而不是 Lotus Note 中的附件 我只是不知道如何解决这个问题 而且我无法访问客户端计算机 这使得调试非常困难 我可以采
    • += 运算符在 C++ 中是如何实现的?

      这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
    • 多个线程访问一个变量

      我在正在读的一本教科书中发现了这个问题 下面也给出了解决方案 我无法理解最小值怎么可能是 2 为什么一个线程不能读取 0 而所有其他线程都执行并写入 1 而无论是1还是2 最后写入的线程仍然必须完成自己的循环 int n 0 int mai
    • 根据 Active Directory 策略检查密码[重复]

      这个问题在这里已经有答案了 我有一个允许用户更改其 AD 密码的前端 有没有办法获取特定用户及其属性 长度 复杂性 的密码策略 例如细粒度 有没有办法根据此特定策略检查字符串 xyz121 编辑 我不想检查活动目录中存储的当前密码 我想检查
    • 线程数组?

      所以我在理解如何避免线程的顺序执行时遇到了问题 我试图创建一个线程数组并在单独的循环中执行 start 和 join 函数 这是我现在拥有的代码示例 private static int w static class wThreads im
    • 原子的 C++ 内存屏障

      在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
    • 重定向 std::cout

      我需要一个类 在其对象的生命周期内将一个 ostream 重定向到另一个 ostream 经过一番修补后 我想出了这个 include
    • 何时分离或加入 boost 线程?

      我有一个方法 大约每 30 秒触发一次 我需要在一个线程中包含它 我有一个可以从类外调用的方法 像 call Threaded Method 这样的东西会创建一个线程 该线程本身会调用最终的线程方法 这些是 MyClass 的方法 void
    • XCode std::thread C++

      对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
    • 模板定义中的友元函数

      我的问题有点相关this https stackoverflow com questions 1297609 overloading friend operator for template class one 我想重载某些类的运算符 te
    • 如何获取运行或段落的高度

      我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd
    • 如何创建实体集或模型而不在数据库中创建相应的表 - 实体框架

      我的 sqlserver 数据库中有一个存储过程 它返回多个结果集 我正在使用 msdn 中的以下链接从实体框架中的 SP 读取多个结果集 https msdn microsoft com en us library jj691402 v
    • 有没有办法在 C# 中仅通过文件名查找文件?

      我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码

    随机推荐

    • 通过引入 T 常量将 Expression> 转换为 Expression>

      我有一个格式为的表达式Expression
    • Crontab 突然停止在服务器上工作?

      我在 Linux 平台上的服务器上设置了一些 crontab 在那 2 天之前 所有 cron 都在运行 我不知道 crontab 发生了什么 它们现在不工作 所有 cron 之前都在运行 之后我添加了一个新的 crontab 它们没有运行
    • HttpWebRequest 对象的诊断转储

      有没有什么好方法 除了繁琐地查询每个属性之外 在 C 中为 HttpWebRequest 构建诊断转储字符串 对于简单的对象 人们可以使用new JObject theObject 但这不适用于 HttpWebRequest 并且toStr
    • 使用 url 创建 yii2 动态页面:www.example.com/pageName

      在我的系统中 用户需要有他们的个人资料页面 我要求这些页面将显示在 url 中 如下所示 www example com John Doe www example com Mary Smith 如何在 yii2 中实现这些 URL 这些 J
    • 使用VBA获取word中的所有交叉引用

      我有一个相当大的 Word 文档 gt 400 页 其中有很多标题的交叉引用 到目前为止 我一直引用标题的标题 但现在我想更改它并引用标题所在的页面 我没有通过 GUI 找到解决方案 当然 手动处理除外 所以我正在考虑编写一些 VBA 不幸
    • XPATH获取text_1和text_2之间的所有节点

      我有这样的 HTML div text1 a link 1 a a link 2 a text2 a link 3 a text3 div 我想获取之间的所有节点text1 and text2 问题是没有p or span标签 只有纯文本
    • Google App Engine 在处理信号后终止:术语

      我有一个应用程序部署为 GCP 上的应用程序引擎 它调用 API 创建 Bytes IO 流并将数据上传到云存储 有 4 个文件 大约 44mb 需要上传 文件是 URL 列表 然后将其提供给数据流 但这并不重要 一开始 我为每个文件创建了
    • 带有负秒的奇怪 mktime 逻辑

      我一直在使用 mktime localtime 进行时间管理 包括一些关于日期 时间的繁重算术 当向 mktime 提供包含负值的 struct tm 时 我注意到一些非常奇怪的事情 采取下面的代码 2013 年 11 月 3 日 洛杉矶的
    • 如何在C中分配和释放对齐内存

      如何分配与 C 中特定边界 例如缓存行边界 对齐的内存 我正在寻找类似 malloc free 的实现 理想情况下应尽可能可移植 至少在 32 位和 64 位架构之间 编辑添加 换句话说 我正在寻找一些行为类似的东西 现在已经过时了 mem
    • 在 R / Rmarkdown 中同步两个传单地图

      JS 传单允许需要同步的两个地图 https github com turban Leaflet Sync 查看同步传单地图示例here http blog thematicmapping org 2013 06 creating sync
    • 在同时活动的多个进程中更新 Java 中的数据

      我正在创建一个带有传感器的令牌环 其中每个传感器都是一个独立的进程 当我启动传感器时 它与网关通信并获取系统上已有的实际传感器的列表 问题是 每次我开始一个新进程时 我希望每个现有的传感器都能获取更新的列表 以便了解其他传感器已被添加 并且
    • 如何制作无限分页的UICollectionView?

      我有一个包含 6 页且启用分页的 UICollectionView 和一个 UIPageControl 我想要的是 当我来到最后一页时 如果我向右拖动 UICollectionView 会从第一页无缝地重新加载 void scrollVie
    • VS 2017 的 .net Core Webpack 发布失败

      我正在尝试将 net Core Angular 4 项目从 Visual Studio 发布到 Azure 在发布过程中 我收到以下错误 ERROR in gendir angular tree component dist compone
    • 求和与分组

      我有一个如下所示的数据框 全部控股基金 BrokerBestRate notional current DistanceBestRate 0 CITI 7 859426e 05 0 023194 1 WFPBS 3 609674e 06 0
    • 如何避免 Observable 中超出最大调用堆栈大小?

      我已经过滤了列表 public filteredEvents new BehaviorSubject 以及反转属性的方法checked export并将更改推回 public checkAll void this filteredEvent
    • Qt 5.5 - 触摸屏事件仅在初始(第一个)窗口中工作

      我已经设置了一个基本的 Qt Widgets Application Qt 5 5 社区 其中包含一个简单的 QWidget MainWindow 和一个附加的 QWidget SettingsScreen 在 MainWindow 中 触
    • Django - 与模型无关的自定义管理页面

      我正在使用 Django 1 7 和 Mezzanine 我希望在管理中有一些页面 工作人员可以在其中使用按钮和其他控制元素调用一些操作 管理命令等 我还想避免创建新模型 或手动创建模板并添加指向它的链接 如果可能 实现这一目标的最常见 最
    • 在 pthread_mutex_init 之前调用 pthread_mutex_lock 是否安全?

      我以前从未有机会使用 pthreads 库 但我正在审查一些涉及 pthread 互斥体的代码 我检查了文档pthread mutex lock and pthread mutex init 通过阅读这两个函数的手册页 我的理解是我必须调用
    • ES6 模块和继承

      我有以下 JavaScript 文件 src js classes Lexus js import Car from src js classes Car export class Lexus extends Car constructor
    • 两个 .NET 线程和硬件访问的问题

      我正在创建一个通过 FT2232H USB RS232 转换器与设备通信的应用程序 为了进行通信 我使用 FTDI 网站上的 FTD2XX NET dll 库 我正在使用两个线程 第一个线程不断从设备读取数据 第二个线程是Windows窗体