关闭\销毁异步方法内的活动

时间:2014-10-31 14:37:36

标签: c# android asynchronous xamarin xamarin.android

经过大量的搜索,我很惊讶没有找到任何关于破坏Android活动的信息,而有一项任务仍在等待:

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 个答案:

答案 0 :(得分: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作为参数并在调用站点中创建CancellationToken。所以在你的代码中我会做类似的事情:

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

然后在Async函数中,在执行活动之前检查令牌的状态。像

这样的东西
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()引发错误,会发生什么/应该发生。

答案 1 :(得分:0)

我不了解Xamarin,但Android的Asynctask类始终与活动绑定,这意味着它将在活动被销毁时停止。

我总是在这种情况下使用service,而不是Asynctask