删除匿名事件处理程序

我有以下代码,其中SprintServiceClient是对WCF服务的引用 –

public class OnlineService { private SprintServiceClient _client; public OnlineService() { _client = new SprintServiceClient(); } public void AddMemberToTeam(MemberModel user, int projectId, Action callback) { _client.AddMemberToTeamCompleted += (s, e) => callback(e.Result); _client.AddMemberToTeamAsync(user.ToUser(), projectId); } } 

问题是,每次调用AddMemberToTeam时,它都会向client.AddMemberToTeamCompleted添加另一个回调。

即第一次调用AddMemberToTeam时,调用一次回调,第二次调用AddMemberToTeam,调用两次ect回调。

有没有办法在调用eventhandler后从AddMemberToTeamCompleted中删除eventhandler或使用另一个接受回调的方法?

只要先将委托分配给变量,就可以从内部引用匿名方法:

 EventHandler handler = null; handler = (s, e) => { _client.AddMemberToTeamCompleted -= handler; callback(e.Result); }; _client.AddMemberToTeamCompleted += handler; 

请注意,您需要声明变量并单独指定它,否则当您在方法体内使用它时,编译器会认为它未初始化。

创建自取消署事件处理程序的技巧是捕获处理程序本身,以便您可以在-=使用它。 但是,有一个声明明确指定的问题; 所以我们做不了类似的事情:

 EventHandler handler = (s, e) => { callback(e.Result); _client.AddMemberToTeamCompleted -= handler; // <===== not yet defined }; 

因此我们首先初始化为null ,因此声明使用之前 ,并且在首次使用之前它具有已知值( null ):

 EventHandler handler = null; handler = (s, e) => { callback(e.Result); _client.AddMemberToTeamCompleted -= handler; }; _client.AddMemberToTeamCompleted += handler; 

不,没有办法,

显然蒂姆和马克有另一个很好的解决方案

但是你总是可以命名它们,并在这个方法上对命名的eventhandler执行-= ;)

猜猜你的活动:

 _client.AddMemberToTeamCompleted += OnAddMemberToTeamCompleted; 

 public void OnAddMemberToTeamCompleted(object sender, EventArgs args) { _client.AddMemberToTeamCompleted -= OnAddMemberToTeamCompleted; callback(e.Result) } 

下一个问题是在您的侦听器中获取此回调。 也许把它放在EventArgs的一个属性上(但感觉有点脏,我同意)