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

本文关键字:内部 活动 异步方法 | 更新日期: 2023-09-27 18:28:33

经过大量搜索,我很惊讶没有发现任何关于破坏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();
        }
    }

尽管在这种情况下有一个明显的变通方法,但我想知道这是否有任何含义。例如,任务持续在后台(或者更糟的是整个活动)。

我没有收到任何错误,尽管点击事件在成功登录时没有收到完成状态。

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

我无法从文档中向您提供详细信息,但我发现(通过在带有调试的真实设备上运行这种类型的异步代码),恢复活动可以尝试恢复正在等待的任务。我解决这个问题的最好方法是使用取消令牌来取消等待的任务。

在我的课上,我有一个私人令牌和令牌源

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 ();
    }
}

我让async方法以CancellationToken作为参数,并在调用站点中创建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()引发错误,会发生什么/应该发生什么。

我不知道Xamarin,但Android的Asynctask类始终与活动绑定,这意味着当活动被破坏时,它将被停止。

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