C#控制台线程

Joh*_*own 5 c# multithreading

我有一个程序,它使用控制台和GUI来完成我的程序的重要方面.我认为这两个部分都使用相同的线程.

问题是我正在使用带有输出的万用表,并且为了从它接收数据,程序发送命令来执行它 - 它使用SCPI,这些命令通过控制台运行.

问题是,每当我向万用表发送命令时,它会使程序无响应,直到它收到数据为止,我知道为什么,我也知道如何解决它,但我想知道是否有更好的方法.

目前我正在更改运行GUI的默认线程:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Thread applicationThread = new Thread(() => Application.Run(new Form1()));
    applicationThread.SetApartmentState(ApartmentState.STA);
    applicationThread.Start();
}
Run Code Online (Sandbox Code Playgroud)

当我向仪表发送命令时,这会阻止程序无响应,但我不能100%确定这是否会产生我还没有看到的任何其他问题?

我的问题是:

  • 有没有更好的方法来更改GUI运行的线程?
  • 如果没有,这种方法是否会产生我尚未看到的任何问题?
  • 我可以改变Console线程吗?

Han*_*ant 3

[STAThread]
static void Main()
Run Code Online (Sandbox Code Playgroud)

这是非常不明智的,你违反了 STAThread 合约。这规定您必须泵送消息循环。.NET 程序中的 Application.Run()。您对显示 UI 的线程执行此操作正确,但对主线程执行此操作不正确。您可能用来与仪表交谈的那个。

最糟糕的问题是,看起来你很容易就能逃脱惩罚。但这是一颗定时炸弹,随时都会在你面前爆炸。不当行为包括任意死锁,尤其是导致 .NET 程序的终结器线程挂起的令人讨厌的死锁。当 CLR 尝试释放 COM 互操作包装器时发生。很难诊断,当内存不足时,你的程序最终会失败。需要一段时间,总是比您测试应用程序的耐心要长。对于仪表对象本身的随机不当行为,通常通过调用对象死锁或对象未引发预期事件来诊断。

终结器线程死锁无疑是最严重的问题,严重到足以迫使您更改此问题。关注真正的问题,这是行为不当的仪表代码。给它一个安全的避风港,一个正确构造的 STA 线程来进行泵送。您将在这篇文章中找到样板代码。或者只是将属性更改为 [MTAThread],这会强制 COM 自己为 COM 对象提供一个安全港。但最好是抓住公牛的角,这样你就知道发生了什么,而不是依赖于无法调试的黑魔法。

我还强烈建议致电该组件的供应商或作者提供支持。单元线程 COM 服务器不应该有这种行为。有些事情出了问题。