C# 订阅的单例类事件未触发
订阅的单例方法未触发-嵌套的windows窗体 向传统应用程序添加对新移动设备的支持 基于本文实现的Singleton类 创建时,每个表单为条形码对象的读取方法预订一个本地方法C# 订阅的单例类事件未触发,c#,windows,mobile,compact-framework,C#,Windows,Mobile,Compact Framework,订阅的单例方法未触发-嵌套的windows窗体 向传统应用程序添加对新移动设备的支持 基于本文实现的Singleton类 创建时,每个表单为条形码对象的读取方法预订一个本地方法 singleton.Instance.scanEngine.BarcodeRead += new BarcodeReadEventHandler(FormA_BarcodeReadMethod); 关闭时,每个表单都会从条形码对象读取方法中取消订阅 singleton.Instance.scanEngine.Barc
singleton.Instance.scanEngine.BarcodeRead += new BarcodeReadEventHandler(FormA_BarcodeReadMethod);
关闭时,每个表单都会从条形码对象读取方法中取消订阅
singleton.Instance.scanEngine.BarcodeRead-=新的BarcodeReadEventHandler(FormA_BarcodeReadMethod)
情景#1
- FormA从主菜单窗体调用
- singleton BarcodeReader.BarcodeScan事件为空李>
- 形式创造
- FormA事件订阅singleton BarcodeReader.BarcodeScan事件 'singleton.Instance.scanEngine.BarcodeRead+=新的BarcodeReadEventHandler(FormA_BarcodeReadMethod);'
- singleton BarcodeReader.BarcodeScan事件不为空
- 条形码扫描和FormA_BarcodeReadMethod激发
- FormA关闭,FormA活动取消订阅给singleton BarcodeReader.BarcodeScan事件singleton.Instance.scanEngine.BarcodeRead-=新的BarcodeReadEventHandler(FormA_BarcodeReadMethod)
- singleton BarcodeReader.BarcodeScan事件为空
- 返回主菜单窗体
- 从主菜单窗体调用FormB
- singleton BarcodeReader.BarcodeScan事件为空李>
- 表格B已创建
- FormB事件订阅singleton singleton.Instance.scanEngine.BarcodeRead+=新的BarcodeReadEventHandler(FormB_BarcodeReadMethod)
- singleton BarcodeReader.BarcodeScan事件不为空
- 条形码扫描并触发FormB_BarcodeReadMethod
using (formC _formC = new formC())
{
_formC.cUser = _cUser;
var _result = _formC.ShowDialog();
if (_result != DialogResult.OK) return;
}
- FormB事件取消订阅singleton BarcodeReader.BarcodeScan事件 singleton.Instance.scanEngine.BarcodeRead-=新的BarcodeReadEventHandler(FormB_BarcodeReadMethod)
- singleton BarcodeReader.BarcodeScan事件为空
- FormC创建
- FormC事件订阅singleton BarcodeReader.BarcodeScan事件 singleton.Instance.scanEngine.BarcodeRead+=新的BarcodeReadEventHandler(FormC_BarcodeReadMethod)
- singleton BarcodeReader.BarcodeScan事件不为空
- 条形码扫描和FormC_BarcodeReadMethod不会触发
- FormC关闭,FormC事件取消订阅singleton BarcodeReader.BarcodeScan事件 singleton.Instance.scanEngine.BarcodeRead-=新的BarcodeReadEventHandler(FormC_BarcodeReadMethod)
clsApplicationController.Instance.scanEngineIntermec.BarcodeRead -= new
BarcodeReadEventHandler(this.frmB_Intermec_OnRead);
this.Update();
Application.DoEvents();
FormC是如下所示的名称
using (formC _formC = new formC())
{
_formC.cUser = _cUser;
var _result = _formC.ShowDialog();
if (_result != DialogResult.OK) return;
}
事件已在FormC构造函数中订阅
clsApplicationController.Instance.scanEngine.BarcodeRead += new
BarcodeReadEventHandler(this.frmC_OnRead);
this.Update();
Application.DoEvents();
对评论的回应#2
已订阅但未触发的FormC事件
void formC_OnRead(object sender, BarcodeReadEventArgs bre)
{
try {
ProcessScan(bre.strDataBuffer, sender);
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
}
formC_OnRead方法订阅formC构造函数中的Instance.scanEngineIntermec.BarcodeRead事件。
ProcessScan是通用的,可供所有扫描仪类型使用。
在工作表单上实现了相同的方法和途径为什么您要取消订阅新的EventHandler,而不在此处减去现有的处理程序: clsApplicationController.Instance.scanEngineIntermec.BarcodeRead-=新的BarcodeReadEventHandler(this.frmB\u Intermec\u OnRead) 通常应为: clsApplicationController.Instance.scanEngineIntermec.BarcodeRead-=this.frmB_Intermec_OnRead 我不确定,但是-=new将取消订阅新的EventHandler。这有意义吗?你所有的表格都使用了-=新的 另见 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 失败的代码是:
void Intermec_OnRead(object sender, BarcodeReadEventArgs bre)
{
try
{
this.textBox1.Text = bre.strDataBuffer;
this.textBox1.Text += "\r\n" + this.Name;
this.textBox1.Text += "\r\n" + sender.ToString();
this.Update();
if (_runFormC)
{
//MessageBox.Show(this.textBox1.Text);
System.Threading.Thread.Sleep(5000);
this.barcodeScanner_unSubscribe();
using (FormC frmC = new FormC())
{
var _result = frmC.ShowDialog();
if (_result != DialogResult.OK) return;
}
this.barcodeScanner_subscribe();
this.textBox1.Text = string.Empty;
}
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
如果从按钮单击处理程序调用formC,则一切正常
当我使用一个队列、一个锁和一个线程来启动formC时,如果队列中有什么东西,formC工作正常。
将所有subscribe()unsubscribe()更改为从激活/停用处理程序调用。我通常喜欢对条形码处理进行一些抽象,以便整个应用程序不依赖于供应商SDK,从而在需要时更容易移植应用程序。我将跳过该切线的细节,但这种方法也简化了整个应用程序中的条形码处理 让您的条形码管理器保持单身,让他成为唯一接触条形码SDK对象的实体。通过调用singleton条形码管理器,让表单或其他对象注册他们对接收条形码通知的兴趣,并将它们保存在堆栈中,以便您可以将条形码通知路由到最顶层的侦听器。因此,在这样一个场景中,您有一个处理条形码的表单,该表单调用一个也处理对话框的对话框B,您不必对任何内容进行微观管理。当显示表单或对话框时,它在加载或激活中调用
BarcodeManager.Instance.PushBarcodeListener(this)
。当它关闭或停用时,您可以调用BarcodeManager.Instance.PopBarcodeListener(this)
。如果您始终使用此选项,Barcodemanager将知道当前用户是谁
void HandleBarcode(BarcodeReadEventArgs evt);
private void PushBarcodeListener(IBarcodeListener l)
{
m_listeners.Push(l);
if (m_listeners.Count == 1)
{
// as soon as you have an interested party, add your one and only
// event handler to the SDK object and enable it (the exact details
// of this are SDK dependent).
}
}
private void PopBarcodeListener(IBarcodeListener l)
{
if (!Object.ReferenceEquals(l, m_listeners.Peek())
Throw new Exception("Only the active BarcodeListener can be removed");
m_listeners.Pop();
if (m_listeners.Count == 0)
{
// if no one is interested in barcodes, stop listening by disabling the SDK
// object and removing the event handler
}
}
if (m_listeners.Count != 0)
m_listeners.Peek().HandleBarcode(evt)
public System.IAsyncResult BeginInvoke(System.Delegate method)
{
return base.MainForm.BeginInvoke(method);
}
public System.IAsyncResult BeginInvoke(System.Delegate method, params object[] args)
{
return base.MainForm.BeginInvoke(method, args);
}