Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关闭\销毁异步方法内的活动_C#_Android_Asynchronous_Xamarin_Xamarin.android - Fatal编程技术网

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

C# 关闭\销毁异步方法内的活动,c#,android,asynchronous,xamarin,xamarin.android,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.bt

在进行了大量搜索之后,我惊讶地发现没有任何关于销毁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();
        }
    }
protectedoverride void OnCreate(捆绑包)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Login);
按钮btnLogin=findviewbyd(Resource.Id.btnLogin);
btnLogin.Click+=async(发送方,e)=>
{
等待验证();
};
}
专用异步任务身份验证()
{
TextView txtUsername=FindViewById(Resource.Id.txtUsername);
TextView txtPassword=findviewbyd(Resource.Id.txtPassword);
if(等待Security.ProcessLogin(txtsername.Text、txtPassword.Text))
{
StartActivity(typeof(actMaiMenu));
这个;
}
其他的
{
\\警告用户
txtUsername.Text=“”;
txtPassword.Text=“”;
txtUsername.RequestFocus();
}
}
虽然在这种情况下有一个明显的解决办法,但我想知道这是否意味着什么。例如,任务持续在后台(或者更糟的是整个活动)


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

我不知道Xamarin,但是Android的
Asynctask
类始终绑定到活动,这意味着当活动被销毁时,它将停止


在这种情况下,我总是使用
服务
,而不是
异步任务

我无法从文档中提供详细信息,但我发现(通过在带有调试的实际设备上运行这种类型的异步代码),恢复活动可以尝试恢复正在等待的任务。我最好的办法就是取消等待的任务

在我的类中,我有一个私有令牌和令牌源

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);
}
然后在异步函数中,在执行活动之前检查令牌的状态。大概是

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

感谢Alex提供了如此详细的答案。如果身份验证任务继续,在您的情况下,您将捕获它并返回,这是绝对正确的。完全同意,如果任务即将陷入进一步的处理\tasks\whatever中,那么如果主任务已恢复,则立即退出主任务非常重要。但是,在这种情况下,我是否可以确认,如果确实发生了,它是否会在离开的.Finish()处重新启动,在任务完成后返回,并退出执行,准备再次单击按钮?我不确定我是否理解这个问题,但这是一个答案。如果在Security.ProcessLogin完成之前请求取消,那么接下来将发生的事情是该方法将返回(不调用任何其他内容)。在这一点上,该方法被发现正在执行,就像任何其他方法一样。如果恢复活动,然后再次单击btnLogin,则将调用整个身份验证方法(包括Security.ProcessLogin)。我并不是完全无视它,但在我的“简单”例子中,如果有一份简历,而且我没有修改我的代码,那么它不会就此结束吗?@AlexC为什么在OnResume中取消?在调用cancelSource.Cancel()之前,您也不需要检查cancelToken,类似于:
if(cancelSource!=null){cancelSource.Cancel();cancelSource=null;}
应该可以做到这一点。