为什么这段VISA仪器/SCPI通信会阻塞UI线程?我们应该如何修复?

编程语言 2026-07-08

这是我们得到的最小可复现示例:一个从零开始在Visual Studio中创建的标准.NET WinForms应用程序,将这段代码粘贴到 Form1.cs 文件中:

using Ivi.Visa;

namespace WinformsJitterTestApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            try
            {
                var session = (IMessageBasedSession)
                    GlobalResourceManager.Open("HV_DMM");

                new Thread(() =>
                {
                    while (true)
                    {
                        session.FormattedIO.WriteLine("MEAS:VOLT:AC? 100, 0.001");
                        var result = session.FormattedIO.ReadLine();

                        Console.WriteLine(result);

                        Thread.Sleep(500);
                    }
                }).Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                throw;
            }
        }
    }
}

The WriteLine and ReadLine operations are freezing the UI when they execute, presumably blocking the UI thread. Copilot has not been able to answer this question, and I have not seen any examples of this happening anywhere else. Yet it is 100% reproducible on our systems.

WriteLineReadLine 操作在执行时会冻结UI,可能阻塞了UI线程。Copilot还无法回答这个问题,我也没有在其他地方看到过类似的例子。不过在我们的系统上却是百分之百可复现。

We have tried various types of multi-threading setups with async/await, Task.Run lambdas, creating a new thread as you see here, creating a whole threading class that should in theory cause all visa operations to run on a background thread, nothing has worked. I don't know why this would have any effect on the UI thread at all as we have even removed the callback writing the information to the form. As you can see there is literally nothing happening in this code on the UI thread at all, other than spinning up the new thread during construction.

我们尝试了多种多线程设置,使用 async/awaitTask.Run 这类Lambda,按你所示创建一个新线程,甚至还创建了一个理论上应该让所有VISA操作都在后台线程中运行的完整线程类,但都没有奏效。 我不知道这对UI线程为什么会有任何影响,因为我们甚至移除了把信息写入窗体的回调。正如你所看到的,这段代码在UI线程上根本没有任何操作,除了在构造期间启动新线程之外。

为什么会这样,我们该如何防止?

EDIT: the instrument we are connecting to is a keysight 34461A, using the IviFoundation.VISA library. The VISA installation being used is from keysight connection expert, although we also had a National Instruments install at one point (which used to be the primary VISA) and behaved the same way.

编辑:我们连接的仪器是Keysight 34461A,使用 IviFoundation.VISA 库。正在使用的VISA安装来自Keysight Connection Expert,虽然曾经也装过National Instruments的版本(曾是主VISA),但行为也相同。

解决方案

The issue seems to be specific to the particular VISA package being used. When I used a COM reference to (for example) VISA COM 5.14 Type Library, that library blocks the UI no matter what I do. Same for the IviFoundation.VISA nuget package.

问题似乎特定于所使用的某个VISA包。例如,当我对VISA COM 5.14 Type Library使用COM引用时,该库无论我怎么做都会阻塞UI。IviFoundation.VISA的 NuGet包也是如此。

But when I use the KeysightTechnologies.Visa NuGet package, the UI no longer freezes when talking to the instrument.

但当我使用KeysightTechnologies.Visa的 NuGet包时,与仪器通信时UI不再卡死。

I have no idea why this is the case, but it solved my problem anyways.

我也不知道为什么会这样,但这确实解决了我的问题。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章