簡體   English   中英

如何避免重復事件訂閱?

[英]How to avoid duplication of event subscription?

我有3個類,即Login,Barcode和Main。
登錄類只包含用戶的身份驗證。
條形碼類具有以下代碼段:

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

    }

在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
      }

    }

當我嘗試注銷並再次登錄時,會發生事件訂閱的重復。
當我嘗試調試時,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;

最好將所有與Barcode一起使用的邏輯移到一個單獨的類中。 並且添加一個自定義事件可能會很好,該事件通知其他類(在您的情況下為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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM