You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms读取FTDI数据时避免UI冻结的Task实现方案

WinForms读取FTDI数据时UI冻结问题排查

开发WinForms GUI应用,通过USB从FTDI芯片读取数据,读取过程中出现UI冻结:窗口失去响应,按钮、最小化/最大化/关闭等窗口控制功能均失效,但Visual Studio调试窗口可见数据正在正常接收。

数据读取基于FTDI驱动的事件机制:ftHandle.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, receivedDataEvent);。理论上数据接收逻辑应放在独立线程中执行以避免阻塞GUI,尝试用Task处理线程但仍出现冻结问题,具体代码如下:

初始实现代码

FTDI初始化后启动接收任务

var receivedDataEvent = new AutoResetEvent(false);

ftHandle.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, receivedDataEvent);

// 创建数据接收任务
Task dataReceiveTask = new Task(async () =>
{
    while (true)
    {
        // 等待FT_EVENT_RXCHAR事件触发
        receivedDataEvent.WaitOne();

        await Task.Run(() =>
        {
            ReadDataAvailableInFtdiBuffer();
        });                    
    }
});

// 启动任务
dataReceiveTask.Start();

数据读取方法

void ReadDataAvailableInFtdiBuffer()
{
    ftStatus = ftHandle.GetRxBytesAvailable(ref numBytesAvailable);
    if (numBytesAvailable < 1)
        return;
    System.Diagnostics.Debug.WriteLine(ftStatus + "  bytes available: " + numBytesAvailable.ToString());

    byte[] bytes = new byte[numBytesAvailable];
    UInt32 numBytesRead = 0;
    ftHandle.Read(bytes, numBytesAvailable, ref numBytesRead);

    // --------------------------------------------------------------------------------------------
    // 触发数据接收事件,将数据传递给订阅者(USB)
    // OnFtdiBytesReceived?.Invoke(this, new FtdiBytesReceivedEventArgs(bytes, numBytesAvailable));
    // --------------------------------------------------------------------------------------------
}

第一次修改(仍未解决UI冻结)

按照建议改用Task.Run直接创建任务,但UI依旧无响应:

var receivedDataEvent = new AutoResetEvent(false);          
ftHandle.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, receivedDataEvent);

// 创建数据接收任务
Task dataReceiveTask = Task.Run(() =>
{
    while (true)
    {
         // 等待FT_EVENT_RXCHAR事件触发
         receivedDataEvent.WaitOne();
         ReadDataAvailableInFtdiBuffer();                                
    }
});

补充:SetEventNotification函数说明

SetEventNotification函数说明
用于设置当指定FTDI事件发生时,触发一个Windows事件对象。

  • 参数1:需要监听的事件(此处为FT_EVENT_RXCHAR,代表接收缓冲区有数据可读取)
  • 参数2:指向要触发的Windows事件对象的指针(此处为AutoResetEvent实例)
    当指定事件发生时,FTDI驱动会将该事件对象置为有信号状态。

内容的提问来源于stack exchange,提问作者bLAZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:25:46