В c # как асинхронное завершение события доступа к свойствам вызывающего класса? - PullRequest
0 голосов
/ 09 декабря 2010

Мы использовали 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, они не могут быть удалены, так что, если я вызову этот код снова, мое событие будет запущено дважды. Поэтому я хочу удалить лямбда-код и сделать это:

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

ОДНАКО: переменная bookMarkId больше не доступна. Я понимаю, что это потому, что лямбда-событие копирует переменную в созданный класс и поддерживает ее в течение всего события. Так как мне сделать то же самое?

Я пытался установить приватную переменную, но покажите, что это можно изменить до получения обратного вызова! Это также относится к коллекции под названием Закладки.

Примечание. Это клиент Silverlight, и я бы предпочел не возвращать коллекцию идентификаторов / идентификаторов в аргументах событий, поскольку это означало бы переработку большого количества кода wcf.

Большое спасибо, Мэтт

ps первый пост в стек, так что успокойся со мной ...

Ответы [ 2 ]

2 голосов
/ 09 декабря 2010

Сохранить обработчик события в локальной переменной;затем вы можете добавить и удалить тот же обработчик событий:

EventHandler<wmdeleteBookMarkCompletedEventArgs> handler = (s, ea) => { .... }
bookMarkClient.wmdeleteBookMarkCompleted += handler;
// ...
bookMarkClient.wmdeleteBookMarkCompleted -= handler;

В качестве альтернативы, лямбда-выражение является просто синтаксическим сахаром для сгенерированного компилятором вложенного класса.Если вы не можете добавить идентификатор закладки в EventArgs, имитируйте лямбду, создав собственный класс:

BookmarkDeletedListener listener = new BookmarkDeletedListener(this, bookMarkId);
bookMarkClient.wmdeleteBookMarkCompleted += listener.DeleteBookmarkCompleted;
bookMarkClient.wmdeleteBookMarkCompleted -= listener.DeleteBookmarkCompleted;

// ...

class BookmarkDeletedListener
{
    public BookmarkDeletedListener(ParentClass parent, string bookmarkId)
    {
        _parent = parent;
        _bookmarkId = bookmarkId;
    }

    public DeleteBookmarkCompleted(object sender, wmdeleteBookMarkCompletedEventArgs e)
    {
        if (ea.Result = "Success")
        {
            foreach (BookMark bookMark in BookMarks)
            {
                if (_bookmarkId == bookMark.bm_id)
                {
                    _parent.BookMarks.Remove(bookMark);
                    _parent.OnNotifyPropertyChanged("BookMarks");
                    break;
                }
            }
        }
    }

    readonly ParentClass _parent;
    readonly string _bookmarkId;
}
0 голосов
/ 09 декабря 2010

Вы можете удалить лямбду, AFAIK, пока вы держитесь за нее.Он может даже удалить себя при увольнении:

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

bookMarkClient.wmdeleteCompleted += handler;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...