2014-10-31 3 views
1

После долгих поисков по всему, я удивлен не найти ничего об уничтожении андроид деятельности, в то время как есть задача все еще ожидает:Закрыть Уничтожить активность Внутри Асинхронный Метод

protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.Login); 
     Button btnLogin = FindViewById<Button>(Resource.Id.btnLogin); 
     btnLogin.Click += async (sender, e) => 
     { 
      await Authenticate(); 
     }; 
    } 

private async Task Authenticate() 
    { 
     TextView txtUsername = FindViewById<TextView>(Resource.Id.txtUsername); 
     TextView txtPassword = FindViewById<TextView>(Resource.Id.txtPassword); 

     if (await Security.ProcessLogin(txtUsername.Text,txtPassword.Text)) 
     { 
      StartActivity(typeof(actMaiMenu)); 
      this.Finish(); 
     } 

     else 
     { 
      \\Warn User 
      txtUsername.Text = ""; 
      txtPassword.Text = ""; 
      txtUsername.RequestFocus(); 
     } 
    } 

Хотя существует очевидная обходной путь в этом случае, мне было интересно, есть ли какие-либо последствия для этого. Например, задача, сохраняющаяся на заднем плане (или, что хуже, вся деятельность).

У меня нет ошибок, несмотря на то, что событие клика не получает статус завершения при успешном входе в систему.

ответ

2

Я не могу дать вам подробную информацию из документации, но я нашел (запустив этот тип асинхронного кода на реальных устройствах с отладкой), что возобновление действий может попытаться возобновить ожидаемые задачи. Лучший способ, который у меня есть, - использовать Cancellation Tokens для отмены ожидаемых задач.

В моем классе у меня есть частный маркер и маркер источника

private CancellationTokenSource cancelSource; 
private CancellationToken cancelToken; 

и в OnResume и OnPause отменить задачу

public override void OnResume() 
{ 
    base.OnResume(); 

    if (cancelToken != null && cancelToken.CanBeCanceled && cancelSource != null) { 
     cancelSource.Cancel(); 
    } 
} 

public override void OnPause() 
{ 
    base.OnPause(); 

    if (cancelToken != null && cancelToken.CanBeCanceled && cancelSource != null) { 
     cancelSource.Cancel(); 
    } 
} 

я делаю метод асинхронной взять CancellationToken в качестве параметра и создать a CancellationToken на сайте вызова. Так что в вашем коде я бы сделать что-то вроде:

btnLogin.Click += async (sender, e) => 
{ 
    cancelSource = new CancellationTokenSource(); 
    cancelToken = cancelSource.Token; 
    this.Authenticate(cancelToken); 
} 

Затем в функции асинхронной проверить состояние Знака перед выполнением мероприятий. Так что-то вроде

private async Task Authenticate(CancellationToken cancellationToken) 
{ 
    .... 
    bool loggedInOk= await Security.ProcessLogin(txtUsername.Text,txtPassword.Text); 
    if (cancellationToken.IsCancellationRequested) 
    { 
     // do something here as task was cancelled mid flight maybe just 
     return; 
    } 

    if (loggedInOk) 
    { 
     StartActivity(typeof(actMaiMenu)); 
     this.Finish(); 
    } 
    else 
    { 
     \\Warn User 
     txtUsername.Text = ""; 
     txtPassword.Text = ""; 
     txtUsername.RequestFocus(); 
    } 
} 

Вы также, вероятно, нужно думать об обработке ошибок, что происходит/должно произойти, если Security.ProcessLogin() вызывает ошибку.

+0

Спасибо, Алекс, за такой подробный ответ. Если задача Authenticate возобновится, в вашем случае вы ее поймаете и вернетесь, что абсолютно нормально. Полностью согласен, что если задача вот-вот застрянет в дальнейшей обработке \ tasks \ whatever, тогда важно сразу же выйти из основной задачи, если она возобновится. Тем не менее, могу ли я подтвердить в этом случае, если это произойдет, будет ли он забираться на этом.Finish(), где он ушел, вернуться из задачи, по мере ее завершения, и завершить выполнение, готов к нажатию кнопки ' еще раз'? – user3280560

+0

Не уверен, что я понимаю вопрос, но вот ответ в любом случае. Если запрос аннулирования запрашивается до завершения Security.ProcessLogin, то следующее, что произойдет, это то, что метод вернется (не вызывая ничего другого). В этот момент метод выполняется финишированием, как и любой другой метод. Если действие возобновлено, а затем btnLogin будет нажат второй раз, будет вызываться весь метод аутентификации (включая Security.ProcessLogin). – AlexC

+0

Я имею в виду, если я не реализую ваше решение. Я не пренебрегаю этим, далеким от, но в моем «простом» примере, если бы было резюме, и я не менял свой код, не так ли? – user3280560

0

Я не знаю о Xamarin, но класс Android Asynctask всегда связан с деятельностью, что означает, что он будет остановлен, когда действие будет уничтожено.

Я всегда использую service для этого случая, а не Asynctask.

Смежные вопросы