2013-04-10 29 views
0

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

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,则该方法的调用在调用GetAnotherListCallBack之前,再次调用方法GetListCallBack

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

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

编辑:

当我使用的,而不是使用this.EMPRepository调用Repository方法效果很好既是回调方法传递给Repository类的不同实例,只有attched回调方法被炒鱿鱼

一个局部变量
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); 
} 

-------- 
+0

您可以更改“ServiceClient”类的代码吗?它应该是固定的东西。 – 2013-04-10 06:57:21

+0

@ MD.Unicorn ServiceClient类是在添加服务引用时由VS自动生成的。 – Raj 2013-05-07 12:59:47

回答

1

第一:

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

被(从功能的POI看到nt of view)相同:

_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); 
} 
+0

感谢您的回复。你所提出的所有观点确实都很有用,而且非常有帮助。最后的代码块当然是取消订阅事件处理程序的绝佳方式。但即使在使用这种方法之后,我也面临同样的问题,并且两种回调方法都会一个接一个地被调用。但是,当我使用局部变量而不是使用'this.EMPRepository'来调用'Repository'方法时,它非常有效,因为这两个CallBack方法都被传递给'Repository'类的不同实例,并且只有attched CallBack方法被触发。 – Raj 2013-05-07 12:57:10

相关问题