【发布时间】:2014-12-27 12:28:15
【问题描述】:
我目前正在开发一个与串行设备通信的 Windows 窗体应用程序。设备供应商提供了一个包含交互方法的 *.dll 文件。我在 Visual Studio 中添加了对 *.dll 文件的引用。
如果我调用设备库 (Get()) 的函数,我会在 2 秒后得到响应。为了避免冻结我的 GUI,我生成了一个新线程,它初始化库对象的一个新实例并调用 Get() 方法。
但是,调用 Get() 会冻结我的 GUI 正好 2 秒。似乎该对象已经在主线程中初始化。
我不知道我在代码中遗漏了什么。这是重现我的问题的代码的 sn-p:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MyDevice deviceObj = new MyDevice();
Thread myThread = new Thread(new ThreadStart(deviceObj.getValues));
myThread.IsBackground = true;
myThread.SetApartmentState(ApartmentState.STA);
myThread.Start();
}
}
class MyDevice
{
public void getValues()
{
// initialize object of device library
Tcddka.tcddk tcd = new Tcddka.tcddk();
// (comPort, identifier, timeout)
tcd.Init((Int16)(3 - 1), "deviceID", 7000);
for (int i = 0; i < 10; i++)
{
tcd.Get(); // measure new values
Thread.Sleep(2000);
}
}
}
提前感谢您的努力,
迈克尔
编辑:解决方案
- 实现STAThread,派生出你自己的类。覆盖 Initialize()(不要忘记调用 base.Initialize() 并在此处创建您的 COM 对象)
- 我的 DLL 库未注册。打开命令行,输入 regsvr32 "你的 DLL 文件的路径"
- 打开注册表,搜索您的 DLL 文件名,浏览到文件夹 InprocServer32 并检查 ThreadingModel 是否设置为 Apartment。
谢谢你们!!
【问题讨论】:
-
您在错误的线程上创建了 MyDevice 对象。 UI 线程而不是工作线程。需要在 STA 线程中调用 Application.Run()。
标签: c# multithreading visual-studio com