在c#中,异步完成的事件应该如何访问调用类的属性?

在c#中,异步完成的事件应该如何访问调用类的属性?,c#,events,asynchronous,lambda,C#,Events,Asynchronous,Lambda,我们一直在使用类似以下的lamda事件: bookMarkClient.wmdeleteCompleted += (s, ea) => { if (ea.Result = "Success") { foreach (BookMark bookMark in BookMarks) { if (bookMarkI

我们一直在使用类似以下的lamda事件:

bookMarkClient.wmdeleteCompleted += (s, ea) =>
        {
            if (ea.Result = "Success")
            {
                foreach (BookMark bookMark in BookMarks)
                    {
                        if (bookMarkId == bookMark.bm_id)
                        {
                            BookMarks.Remove(bookMark);
                            OnNotifyPropertyChanged("BookMarks");
                            break;
                        }
                    }                
               }
        };

        bookMarkClient.wmdeleteBookMarkAsync(bookMarkId);
然而,根据stackoverflow上的许多答案,这些不能被删除,因此,如果我再次调用此代码,我的事件将被触发两次。因此,我想删除lambda代码并执行以下操作:

//in the class constructor
bookMarkClient.wmdeleteBookMarkCompleted += new EventHandler<wmdeleteBookMarkCompletedEventArgs>(bookMarkClient_wmdeleteBookMarkCompleted);

//Proc on the same class
 void bookMarkClient_wmdeleteBookMarkCompleted(object sender, wmdeleteBookMarkCompletedEventArgs e)
        {
            if (ea.Result = "Success")
            {
                foreach (BookMark bookMark in BookMarks)
                {
                   if (bookMarkId == bookMark.bm_id)
                    {
                        BookMarks.Remove(bookMark);
                        OnNotifyPropertyChanged("BookMarks");
                        break;
                    }
                }
            }

              }

//on button click
bookMarkClient.wmdeleteBookMarkAsync(bookMarkId);
//在类构造函数中
bookMarkClient.wmdeleteBookMarkCompleted+=新事件处理程序(bookMarkClient\u wmdeleteBookMarkCompleted);
//处理同一类
无效书签客户端\u wmDeleteBookmark已完成(对象发送方,wmdeleteBookMarkCompletedEventArgs e)
{
如果(ea.Result=“Success”)
{
foreach(书签中的书签)
{
if(bookMark id==bookMark.bm_id)
{
书签。删除(书签);
OnNotifyPropertyChanged(“书签”);
打破
}
}
}
}
//点击按钮
bookMarkClient.wmdeletebookmarksync(bookMarkId);
但是:变量bookmark id不再可用。我理解这是因为lambda事件将变量复制到构造的类中,并使其在事件期间保持活动状态那么我该怎么做呢?

我已经尝试设置一个私有变量,但测试表明,在收到回调之前可以更改它!这也适用于名为Bookmarks的集合

注意,这是一个Silverlight客户端,我不希望在事件args中传回Id/集合,因为这意味着要重写大量wcf代码

非常感谢,马特


ps first post to stack,让我轻松一点…

将事件处理程序存储在局部变量中;然后可以添加和删除相同的事件处理程序:

EventHandler<wmdeleteBookMarkCompletedEventArgs> handler = (s, ea) => { .... }
bookMarkClient.wmdeleteBookMarkCompleted += handler;
// ...
bookMarkClient.wmdeleteBookMarkCompleted -= handler;
你可以移除一个lambda,AFAIK,只要你抓住它。它甚至可以在启动时自行移除:

Action<object, wmdeleteBookMarkCompletedEventArgs> handler;
handler =
    (s, ea) =>
        {
            bookMarkClient.wmdeleteCompleted -= handler;
            if (ea.Result == "Success")
            ...
        };

bookMarkClient.wmdeleteCompleted += handler;
动作处理程序;
处理者=
(s,ea)=>
{
bookMarkClient.wmdeleteCompleted-=处理程序;
如果(ea.Result==“成功”)
...
};
bookMarkClient.wmdeleteCompleted+=处理程序;

感谢您的快速响应。这会产生一个错误“使用未分配的局部变量‘handler’”。不管怎样,我已经有了一些类似的代码,但我希望在创建客户端时使用更清晰地附加到客户端的事件。因此,问题仍然存在,我如何获得类属性的访问权[在调用异步方法时它们处于的状态]?后续:如果处理程序被定义为类上的私有变量,那么上面的示例[似乎]起作用。但是,如果处理程序被定义为局部变量(在调用过程中),那么编译器会抱怨。但我还是不知道我的问题的答案!代码缺少一个小细节。第一行需要在“handler”和“;”之间添加“=null”。这是C#的“确定赋值”规则的结果。(可以说编译器有点偏执,但解决这个问题很容易。)这篇最近的博文也很有用:谢谢,根据我对另一个答案的回复,我尝试使用局部变量删除lambda,结果好坏参半。您的解决方案看起来是可行的,但我不确定在何处声明listner,然后向处理程序声明。如果我添加它,调用async方法,然后在下一行删除它,那么永远不会收到回调!最后,它迫使我将书签和onNotifyPropertyChanged公开(不理想)。马特
Action<object, wmdeleteBookMarkCompletedEventArgs> handler;
handler =
    (s, ea) =>
        {
            bookMarkClient.wmdeleteCompleted -= handler;
            if (ea.Result == "Success")
            ...
        };

bookMarkClient.wmdeleteCompleted += handler;