简体   繁体   English

如何避免重复事件订阅?

[英]How to avoid duplication of event subscription?

I have 3 classes namely Login, Barcode, and the Main. 我有3个类,即Login,Barcode和Main。
Login class just contains the authentication of the users. 登录类只包含用户的身份验证。
Barcode class has the following snippet code: 条形码类具有以下代码段:

    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);
      }

    }

While in Main class, the subsciption of the Barcode event is done: 在Main类中,Barcode事件的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
      }

    }

The duplication of event subscription happens when I try to logout and login again. 当我尝试注销并再次登录时,会发生事件订阅的重复。
When I tried to debug, BarcodeReadOut is called twice. 当我尝试调试时,BarcodeReadOut被调用两次。
In logout, the removeInstance() is called and the Main form is Close() and Dispose() before opening the login screen. 在注销中,在打开登录屏幕之前调用removeInstance()并且Main表单是Close()和Dispose()。
Can someone help me on how can I avoid the duplication of the said events? 有人可以帮助我如何避免重复上述事件?

I also have done this before registering the event but nothing happens: 在注册事件之前我也做过这个,但没有任何反应:

    public Main()
    {
        barcode.BarcodeReadOut -= new barcode.BarcodeReadHandler(getBarcodeStr);
        barcode.BarcodeReadOut += new barcode.BarcodeReadHandler(getBarcodeStr);
    }

You should add and remove the handler as follows: 您应该按如下方式添加和删除处理程序:

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
  }

}

Also: You don't need to define a custom delegate, you can use the generic EventHandler : 另外:您不需要定义自定义委托,您可以使用通用EventHandler

public event EventHandler<BarcodeEventArgs> BarcodeReadOut;

It would be good to move all your logic that works with Barcode to a separate class. 最好将所有与Barcode一起使用的逻辑移到一个单独的类中。 And it might be good to add a custom event that notifies other classes (a Form class in your case) that event has occurred : 并且添加一个自定义事件可能会很好,该事件通知其他类(在您的情况下为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);
    }
}

And use it like this: 并像这样使用它:

BarcodeWorker barcode = new BarcodeWorker();

barcode.scanComplete += // your delegate with event handler or with anonymous method here;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM