我制作了一个小测试程序,尝试让 USB 读卡器使用制造商提供的 ActiveX 控件工作。
只要不使用单独的线程,表单就可以正常工作。我创建了一个新实例Reader
并收听该Read
事件,一切正常。我刷卡,事件触发并且文本框得到更新。
private Reader _reader;
public Form1()
{
InitializeComponent();
CreateScanner();
}
public void CreateScanner()
{
_reader = new Reader();
_reader.Read += Read;
}
void Read(object sender, EventArgs e)
{
CardData.Text = "Card Read";
}
阅读器类以防万一:
public class Reader
{
private AxUSBHIDInsert _axUsbHid;
public event EventHandler Read;
public Reader()
{
_axUsbHid = new AxUSBHIDInsert();
_axUsbHid.CreateControl();
_axUsbHid.BeginInit();
_axUsbHid.MSRReadDir = MSRReadDirection.ReadWithdrawal;
_axUsbHid.EndInit();
_axUsbHid.PortOpen = true;
_axUsbHid.CardDataChanged += CardDataChanged;
}
void CardDataChanged(object sender, EventArgs e)
{
if (Read != null)
Read(this, new EventArgs());
}
}
但是,我需要在单独的线程上运行它。所以我将构造函数更改为
Thread thread = new Thread(CreateScanner);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
它必须是一个 STA 线程,否则 ActiveX 控件会抱怨它不能被实例化。但是这样做,事件不再触发。我对线程的工作原理不太熟悉,所以我不确定为什么。
有任何想法吗?请注意,它必须以这种方式工作(单独的线程,连接到 Read 事件),因为代码最终将驻留在类库中,该类库与我无法更改的应用程序一起部署。