2015-07-22 99 views
5

我有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); 
    } 
+2

可以清除所有带反射的eventsubscriptions。看看这里http://stackoverflow.com/questions/91778/how-to-remove-all-event-handlers-from-a-control –

+1

你可以检查'barcode.BarcodeReadOut == null' – Hassan

+1

上面的链接是好的,但一定要阅读,因为接受的答案似乎不是最好的。 – TaW

回答

0

你应该添加和删除处理程序如下:

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; 
0

这将是很好将所有适用于条码的逻辑移至单独的类。它可能是很好的补充通知(在你的情况下,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;