unity3d 除非在局部变量中分配任务.结果,否则不维护任务isFaulted状态

yc0p9oo0  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(115)

请考虑以下代码片段:

public Task SignInWithEmailAndPasswordAsync(string email, string password) {
        return auth.SignInWithEmailAndPasswordAsync(email, password).ContinueWith(task => {
            if (task.IsCanceled) 
                Debug.LogError("SignInWithEmailAndPasswordAsync was canceled.");
            if (task.IsFaulted) 
                Debug.LogError("SignInWithEmailAndPasswordAsync encountered an error: " + task.Exception);
            var result = task.Result; // I need to do this to maintain the task fail status
        });
    }

如果我从代码的其他部分调用这个方法,像这样:

var loginTask = firebaseManager.SignInWithEmailAndPasswordAsync(username, password);
yield return new WaitUntil(predicate: () => loginTask.IsCompleted);
Debug.Log(loginTask.IsFaulted) // true if I dont do var result = task.Result; in the original task

如果任务失败,我需要执行var result = task.Result;来维护IsFaulted的状态。如果没有这行代码,它总是为true(即使任务失败)。
为什么?

8wtpewkr

8wtpewkr1#

ContinueWith将返回一个新的Task,而不是它继续执行的Task,这是有道理的。因此,当调用SignInWithEmailAndPasswordAsync时,.IsFaulted将始终是false,因为事实上,您在ContinueWith中创建的Task没有错误。
然而,当你试图在.ContinueWith方法中访问task.Result时,它会重新抛出异常,因此新任务也是错误的。你想要在代码中做的事情如下所示:

public Task SignInWithEmailAndPasswordAsync(string email, string password) 
{
    return auth.SignInWithEmailAndPasswordAsync(email, password)
        .ContinueWith(
            task =>
            {
                if (task.IsFaulted)
                    Console.WriteLine("faulted");
            
                return task;
            }).Unwrap();
}

实际上,ContinueWith将返回Task<Task>,其中外部Task表示ContinueWith,内部Task表示它作为前一个接收到的Task。现在,当您调用Unwrap时,只会返回内部任务。

相关问题