Обратный вызов Silverlight 4 накапливается при каждом нажатии кнопки - PullRequest
0 голосов
/ 13 ноября 2010

Я пишу приложение Silverlight 4, используя «Silverlight 4 Unleashed» в качестве основы.

У меня есть ChildWindow для входа в систему с именем пользователя, паролем и Запомнить меня.Кнопка «ОК» привязана к моему входу в AuthUserViewModel с использованием RelayCommand.

Поскольку я только начинаю, у меня еще нет никакой проверки данных, и я заметил что-то странное.

Если я нажму «ОК»"в моем дочернем окне входа в систему мой обратный вызов Action сообщает мне, что у меня есть недействительные учетные данные в MessageBox ... что идеально.Я использую свою собственную службу аутентификации по разным причинам.

Однако, если я снова нажму «ОК», моя служба будет вызываться один раз, но дважды вызывается обратный вызов Action, сообщая, что у меня неверные учетные данные.Если я снова нажму «ОК», служба будет вызываться один раз, но обратный вызов Action будет запущен три раза и т. Д. И т. Д.

Зачем это нужно делать?

Здесьэто код ошибки:

public void SignIn(AuthUserDataModel authUser, Action<ErrorContainer> callback)
{
    EnsureClient();
    client.SignInCompleted += (sender, result) =>
    callback(new ErrorContainer
    {
        AsyncException = result.Error,
        CustomError = result.Result.CustomMessage  //holds "Invalid credentials"
    });

    client.SignInAsync(authUser);
}

Как я уже сказал, событие кнопки вызывается один раз, веб-служба вызывается один раз, а обратный вызов запускается на сумму, равную числу нажатий кнопки ОК.

Спасибо.

1 Ответ

1 голос
/ 14 ноября 2010

Ах! Ваш клиентский объект является полем, и вы гарантировали, что он является общим для вызовов. Он предотвращает инициализацию при каждом вызове SignIn, но каждый раз, когда вы добавляете обработчик в вентиляцию SignInCompleted перед выполнением SignInAsyncFunction.

Поэтому нормально, что обработчик выполняется один раз при последующем входе.

Чтобы предотвратить это, у вас есть 2 подхода:

1) создавать нового клиента при каждом вызове входа в систему (это будет сборка мусора позже)

2) прикрепите ваш обработчик при инициализации клиента. т.е. в вашем EnsureClient вы должны иметь что-то вроде:

if(client == null)
{
    client = new MyClient();
    client.SignInCompleted +=(sender,result) =>{...};
}

и в функции входа в систему:

EnsureClient();
client.SignInAsync(authUser);
...