Eventhandler没有取消订阅

时间:2013-04-10 06:52:00

标签: c# silverlight events delegates

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

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()的调用已完成,然后我在同一个类GetAnotherList()中调用另一个方法EmpViewModel时,再次调用GetListCallBack方法在调用GetAnotherListCallBack之前。

这可能发生,因为两种方法都订阅了该事件。

正如您所看到的,我已经明确地从回调事件中取消订阅了事件处理程序,但仍然调用了事件处理程序。 任何人都可以建议我可能出错的地方吗?

编辑:

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

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

--------

1 个答案:

答案 0 :(得分:1)

首先:

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

(从功能的角度来看)与:

相同
_client.GetListCompleted += eventHandler;

现在你立即看到了问题。您的代码是:

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

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

我想你想删除旧的eventhandler并添加一个新的。因此,您的函数应该获取旧的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);
}