【问题标题】:Using Await in a Catch Block [duplicate]在 Catch 块中使用 Await [重复]
【发布时间】:2013-12-30 01:41:03
【问题描述】:

在我的应用程序中,用户尝试登录。有时,即使凭据正确,网站也会登录失败,并要求用户输入验证码。这意味着他们必须尝试登录两次。

我的应用程序有 2 个自定义异常,这些异常会在登录失败或网站要求用户输入验证码时引发。他们在这里:

class LoginFailedException : Exception
{
    public LoginFailedException() { }
    public LoginFailedException(string message) : base(message) { }
}

class LoginFailedCaptchaRequiredException : Exception
{
    public LoginFailedCaptchaRequiredException() { }
    public LoginFailedCaptchaRequiredException(string message) : base(message) { }
}

在我的应用程序中,我捕获了这两个异常。当LoginFailedCaptchaRequiredException 被抛出时,我会抓住它,但我需要使用验证码图像向用户显示一个对话框,要求他们输入验证码图像中的文本。一旦他们输入了文本,我就需要调用“await LoginWithCaptcha”。

但问题是我不能在catch 中使用await。我可以在这里尝试哪些替代解决方案?

这是我的登录按钮:

private async void btnLogin_Click(object sender, EventArgs e)
{
        try
        {
            webclient = new WebsiteAPI("username", "password");
            await webclient.Login();
            MessageBox.Show("Logged In");
        }
        catch (LoginFailedException ex)
        {
            MessageBox.Show("Login Failed");
        }
        catch (LoginFailedCaptchaRequiredException ex)
        {
            // 1. Show dialog with Captcha
            // 2. Get captcha text entered by user
            // 3. await LoginWithCaptcha(string captchaText, string captchaKey);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Something Bad Happened");
        }
    }

我该如何解决这个问题?

【问题讨论】:

  • 在捕捞之外做吗?
  • 我忘记添加了。我一直在遵循一本名为 Clean Code 的书中教授的许多实践。作者指出,如果可能,当函数中使用 try/catch 块时,不应在 try/catch 块之前或之后出现任何内容。我正在遵循良好的设计实践以保持功能小(仍然需要重构)。我发现的解决方案都没有考虑到这一点。
  • @JamesJeffery 你并不总是能成功地将非异步代码的实践应用于异步代码。虽然await 确实让它看起来更相似,但仍然存在差异,并且它确实需要至少对编码实践产生一些影响。

标签: c# async-await


【解决方案1】:

catch块简单表示你有一些工作要做,然后在整个try/finally结束后做:

bool tryToLoginWithCaptcha = false;

try
{
    //...
}
catch (LoginFailedCaptchaRequiredException ex)
{
    // 1. Show dialog with Captcha
    // 2. Get captcha text entered by user
    tryToLoginWithCaptcha = true;
}

if(tryToLoginWithCaptcha)
    await LoginWithCaptcha(captchaText, captchaKey);

如果您对要做什么有更复杂的决定,那么您当然可以使用 List<Task>await 而不仅仅是布尔值。

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 2017-08-22
    • 1970-01-01
    • 2012-10-04
    • 2015-10-03
    • 1970-01-01
    • 2018-03-20
    • 2018-06-21
    • 2019-08-13
    相关资源
    最近更新 更多