C#控制台线程

问题描述 投票:5回答:1

我有一个程序,它使用控制台和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();
}

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

我的问题是:

  • 有没有更好的方法来更改GUI运行的线程?
  • 如果没有,这种方法是否会产生我尚未看到的任何问题?
  • 我可以改变Console线程吗?
c# multithreading
1个回答
3
投票
[STAThread]
static void Main()

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

最糟糕的问题是它很容易看起来像你会逃脱它。但它是一颗滴答作响的定时炸弹,随时准备在你脸上爆炸。不良行为的范围从任意死锁,特别是使.NET程序的终结器线程挂起的令人讨厌的类型。当CLR尝试释放COM互操作包装时发生。非常难以诊断,当程序内存不足时,程序最终会崩溃。需要一段时间,总是比耐心测试应用程序更长。对于仪表对象本身的随机不当行为,通常通过调用对象死锁或未引发预期事件的对象来诊断。

终结器线程死锁肯定是最糟糕的问题,足以迫使你改变它。专注于真正的问题,仪表代码是行为不端的。给它一个安全的避风港,一个正确构造的STA螺纹泵。你会在this post找到样板代码。或者只是将属性更改为[MTAThread],这会强制COM自己为COM对象提供安全的避风港。但最好把它的号角拿走,以便你知道发生了什么,而不是依赖于不可摧毁的黑魔法。

我还强烈建议对该组件的供应商或作者进行支持。单元线程COM服务器不应该以这种方式运行。有点不对劲。

© www.soinside.com 2019 - 2024. All rights reserved.