eventandler没有取消订阅

本文关键字:取消 eventandler | 更新日期: 2023-09-27 18:08:17

在我的silverlight应用程序中,我将一个方法GetListCallBack传递给Repository类中另一个方法GetEmployees的委托参数,该方法将该委托作为eventandler附加到异步服务调用的完成事件。

EmpViewModel类:

public class EmpViewModel
{
  private IRepository EMPRepository = null;
  //constructor
  public EmpViewModel
  {
    this.EMPRepository= new Repository();
  }
  public void GetList()
  {
     this.EMPRepository.GetEmployees(xyz, this.GetListCallBack);
  }
  public void GetAnotherList()
  {
     this.EMPRepository.GetEmployees(pqr, this.GetAnotherListCallBack);
  }

  private void GetListCallBack(object sender, GetListCompletedEventArgs args)
  {
        if (args.Error == null)
        {
            this.collection1.Clear();
            this.collection1 = args.Result;
        }
        else
        {
            //do sth
        }
  }
  public void GetAnotherListCallback(object sender, GetListCompletedEventArgs args)
  {
     //do sth with collection1
  }
}

库类:

public class Repository : IRepository
{
    private readonly ServiceClient _client=null ;
    public Repository()
    {
        _client = new ServiceClient(Binding, Endpoint);
    }
    public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler)
    {
        _client.GetListCompleted -= eventHandler;
        _client.GetListCompleted += new EventHandler<GetListCompletedEventArgs>(eventHandler);
        _client.GetListAsync(xyz);
    }
}

现在,当对方法GetList()的调用已经完成,然后如果我在同一个类EmpViewModel中调用另一个方法GetAnotherList(),那么GetListCallBack方法在GetAnotherListCallBack被调用之前再次被调用。

这可能发生在两个方法都订阅了事件时。

正如您所看到的,我已经明确地从回调事件中取消订阅了事件处理程序,但事件处理程序仍然被调用。谁能告诉我哪里做错了吗?

编辑:

当我使用局部变量而不是使用this.EMPRepository来调用Repository方法时,它工作得很好,因为两个回调方法都传递给Repository类的不同实例,只有附加的回调方法被触发

public class EmpViewModel
{
 public void GetList()
 {
  EMPRepository = new Repository();
  EMPRepository.GetEmployees(xyz, this.GetListCallBack);
 }
public void GetAnotherList()
{
EMPRepository = new Repository();
EMPRepository.GetEmployees(pqr, this.GetAnotherListCallBack);
}  
--------

eventandler没有取消订阅

First:

_client.GetListCompleted += new EventHandler<GetListCompletedEventArgs>(eventHandler);

(从功能的角度来看)与

相同:
_client.GetListCompleted += eventHandler;

现在你马上就看到问题了。你的代码是:

_client.GetListCompleted -= eventHandler;
_client.GetListCompleted += eventHandler;

如果你在下一行添加了事件处理程序,为什么要删除它呢?

我猜你想要删除旧的事件处理程序并添加一个新的。你的函数应该获得一个委托给旧的事件处理程序来移除。像这样:

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> oldEventHandler, EventHandler<GetListCompletedEventArgs> newEventHandler)
{
    _client.GetListCompleted -= oldEventHandler;
    _client.GetListCompleted += newEventHandler;
    _client.GetListAsync(xyz);
}

但这可能吗?

如果您可以控制ServiceClient.GetListCompleted,为什么不删除event关键字并只分配该委托,如:

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler)
{
    _client.GetListCompleted = eventHandler;
    _client.GetListAsync(xyz);
}

还是……如果委托在GetListASync中只被调用一次:

public void GetEmployees(int xyz, EventHandler<GetListCompletedEventArgs> eventHandler)
{
    _client.GetListCompleted += (sender, args) =>
    {
        eventHandler(sender, e); 
        _client.GetListCompleted -= eventHandler;
    };
    _client.GetListAsync(xyz);
}