gpt4 book ai didi

c# - 处理异步方法的取消

转载 作者:行者123 更新时间:2023-11-30 15:31:02 25 4
gpt4 key购买 nike

我正在使用 Parse作为应用程序的数据存储,我正在实现他们的 Facebook Login功能。 AFAIK,此登录方法与其他异步方法没有任何不同,因此希望它适用。

所以有一个 Login.xaml 页面,其中有一个“使用 Facebook 登录”按钮,点击此按钮会将您带到仅包含 WebBrowser 的 FacebookLogin.xaml 页面。根据链接的 Parse 文档进行控制。在 ContentPanel.Loaded在 FacebookLogin.xaml 上,我可以使用以下代码登录:

async void FacebookLogin()
{
try
{
user = await ParseFacebookUtils.LogInAsync(fbBrowser, new[] { "user_likes", "email" });
}
catch (OperationCanceledException oce)
{
// task was cancelled, try again
//task = null;
//FacebookLogin();
}
catch (Exception ex)
{
}
}

如果我真的登录了,它会起作用,我可以将用户导航到下一页。当我让浏览器控件加载(所以 async 方法是 waiting),然后点击 Back 按钮,然后返回到Facebook 登录页面

当我这样做时,一个 OperationCancelledException被抛出,但我不确定如何处理它。我试过的:

  1. catch对于 OperationCanceledException , 设置重新初始化 WebBrowser控制到一个新的。这没有效果。

  2. 在同一catch , 调用 FacebookLogin()再次,重试。这也没有用。

  3. 我也试过不使用 await并返回 Task<ParseUser>但我也不确定该怎么做。

我可以对取消异常做些什么,或者使用 CancellationToken更好地处理这个?我只想正确处理取消,以便在用户按下“后退”时重新加载 Facebook 登录页面。

解决方案:

好的,在@JNYRanger 的大量指导下,我想出了一个可行的解决方案。可能有更好的方法,但这似乎有效。这是我的 FacebookLogin.xaml 中的完整代码:

public partial class LoginFacebook : PhoneApplicationPage
{
Task<ParseUser> task;
CancellationTokenSource source;

public LoginFacebook()
{
InitializeComponent();
ContentPanel.Loaded += ContentPanel_Loaded;
}

async void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
try {
source = new CancellationTokenSource();
task = ParseFacebookUtils.LogInAsync(fbBrowser, new[] { "user_likes" }, source.Token);
await task;

// Logged in! Move on...
}
catch (Exception ex) { task = null; }
}

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (task != null) source.Cancel(false);
base.OnBackKeyPress(e);
}
}

所以基本上,当按下“后退”时,我使用 CancellationToken请求取消,这会引发异常。当异常发生时,我设置了task为空。现在,当重新导航到 Facebook 登录页面(之前没有登录)时,task可以成功重建。

最佳答案

永远不要有 async void 方法。您无法在其中正确处理异常。如果您的 async 方法不返回任何内容,请改用 async Task(非通用)作为返回类型。

然后您可以等待返回的 Task 以正确处理异常。

如果您要设置使用 CancellationTokens,请将 CancellationTokenSource 的 token 传递给 async 方法。然后,您可以将此 token 注册到回调或继续将 token 传递到 LoginAsync 方法(如果该重载可用)。我用了这个MSDN article让我自己熟悉取消方法。

另请参阅 MSDN 博客中关于避免 async void 问题的这篇文章:Async-Await Best Practices

编辑
根据您问题中的编辑,我想指出一些事情。如果您调用

Task<ParseUser> t = FacebookLogin()

您现在有了一个可以用来执行操作的 Task 对象。但是,如果您只想要 ParseUser 对象并且没有延续或需要对 Task 做任何其他事情,您应该再次使用 await

ParseUser p = await FacebookLogin();

因为这是在一个事件处理程序中(已加载),所以它是一个可以使用 async void

的异常

至于发生取消时会发生什么,这取决于您。可以关闭登录窗口,取消其他任务/方法等。

关于c# - 处理异步方法的取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21248000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com