如何避免重复订阅活动?
问题描述:
我有3个类,即登录,条码和主。
登录类只包含用户的身份验证。
条码类具有以下代码片段:如何避免重复订阅活动?
class Barcode
{
public delegate void BarcodeReadHandler(object sender, BarcodeEventArgs e);
public event BarcodeReadHandler BarcodeReadOut;
public Barcode()
{
//.. some codes for getting data on the scanner
BarcodeEventArgs args = new BarcodeEventArgs(scannedData);
BarcodeReadOut(this, args);
}
}
而在主类,条形码事件的subsciption完成:
public partial class Main : Form
{
private Barcode barcode = null;
public Main()
{
barcode.BarcodeReadOut += new barcode.BarcodeReadHandler(getBarcodeStr);
}
//This is called before log-out.
public void removeInstance()
{
barcode.BarcodeReadOut -= new barcode.BarcodeReadHandler(getBarcodeStr);
}
private void getBarcodeStr(object sender, BarcodeEventArgs e)
{
//some code
}
}
事件订阅的重复,当我尝试注销并发生再次登录。
当我尝试调试时,BarcodeReadOut被调用两次。
在注销时,在打开登录屏幕之前调用removeInstance(),并且Main窗体为Close()和Dispose()。
有人可以帮助我如何避免上述事件的重复?
我也注册了事件之前这样做,但什么也没有发生:
public Main()
{
barcode.BarcodeReadOut -= new barcode.BarcodeReadHandler(getBarcodeStr);
barcode.BarcodeReadOut += new barcode.BarcodeReadHandler(getBarcodeStr);
}
答
你应该添加和删除处理程序如下:
public partial class Main : Form
{
private Barcode barcode = null;
public Main()
{
barcode.BarcodeReadOut += getBarcodeStr;
}
//This is called before log-out.
public void removeInstance()
{
barcode.BarcodeReadOut -= getBarcodeStr;
}
private void getBarcodeStr(object sender, BarcodeEventArgs e)
{
//some code
}
}
另外:你并不需要定义自定义委托,您可以使用通用的EventHandler
:
public event EventHandler<BarcodeEventArgs> BarcodeReadOut;
答
这将是很好将所有适用于条码的逻辑移至单独的类。它可能是很好的补充通知(在你的情况下,Form类)其他类已发生的事件自定义事件:
class Barcode
{
public delegate void BarcodeReadHandler(object sender, BarcodeEventArgs e);
public event BarcodeReadHandler BarcodeReadOut;
public Barcode()
{
//.. some codes for getting data on the scanner
BarcodeEventArgs args = new BarcodeEventArgs(scannedData);
BarcodeReadOut(this, args);
}
}
class BarcodeWorker
{
private Barcode barcode = null;
private BarcodeReadHandler handler;
public event BarcodeEventArgs scanComplete;
BarcodeWorker(Barcode barcode)
{
if(barcode == null) this.barcode = barcode;
}
public AddEventHandler()
{
if(handler != null) return;
handler = new BarcodeReadHandler(getBarcodeStr);
barcode.BarcodeReadOut += handler;
}
//This is called before log-out.
public void RemoveEventHandler()
{
barcode.BarcodeReadOut -= handler;
handler = null;
}
private void getBarcodeStr(object sender, BarcodeEventArgs e)
{
scanComplete(sender, e);
}
}
,并使用它像这样:
BarcodeWorker barcode = new BarcodeWorker();
barcode.scanComplete += // your delegate with event handler or with anonymous method here;
可以清除所有带反射的eventsubscriptions。看看这里http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control –
你可以检查'barcode.BarcodeReadOut == null' – Hassan
上面的链接是好的,但一定要阅读,因为接受的答案似乎不是最好的。 – TaW