如何解决如何在其他线程上收听此事件?
| 我已经编写了一些测试程序,以尝试使用制造商提供的ActiveX控件使USB读卡器正常工作。 只要不使用单独的线程,该表单就可以正常工作。我创建了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事件),因为代码最终将驻留在一个类库中,该类库与无法更改的应用程序一起部署。
解决方法
您的COM对象将消息发送到第二个线程,这意味着它必须在应用程序运行期间一直处于活动状态。
尝试这样做:
public class Reader
{
public Reader()
{
// leave empty
}
public Read() {
_axUsbHid = new AxUSBHIDInsert();
...
}
}
public Form1()
{
InitializeComponent();
_reader = new Reader();
_reader.Read += Read;
StartRead(_reader);
}
void StartRead(Reader reader) {
Thread thread = new Thread(ReadRoutine);
thread.SetApartmentState(ApartmentState.STA);
thread.Start(reader);
}
void ReadRoutine(object param) {
Reader reader = (Reader)param;
reader.Read();
while (AppIsAlive) { // add logic here
// bad code,import GetMessage from user32.dll
Application.DoEvents();
Thread.Sleep(100);
}
}
但是必须同步处理Read事件:
void Read(object sender,EventArgs e)
{
if (this.InvokeRequired)
this.BeginInvoke(new EventHandler(Read),new object[2] { sender,e } );
else {
CardData.Text = \"Card Read\";
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。