【问题标题】:Returning exception from try/catch within Task.Run C#从 Task.Run C# 中的 try/catch 返回异常
【发布时间】:2018-02-18 15:38:16
【问题描述】:

我正在尝试使用网络表单上的按钮来处理将用户添加到邮件黑猩猩的过程。我有两个函数...一个按钮函数调用调用 API 的异步函数。

public class MailChimpResponse
{
    public bool IsSuccessful;
    public string ReponseMessage;
}

public void SubscribeEmail(object Sender, EventArgs e)
{
    var mcResponse = SubscribeEmailAsync();
    var result = mcResponse.Result;

    if (result.IsSuccessful == true)
    {
        lblSuccess.Text = result.ReponseMessage;
        pnlSuccess.Visible = true;
    }
    else
    {
        lblError.Text = result.ReponseMessage;
        pnlError.Visible = false;
    }
}

public async Task<MailChimpResponse> SubscribeEmailAsync()
{
    IMailChimpManager mailChimpManager = new MailChimpManager(ConfigurationManager.AppSettings["testing"]);
    MailChimpResponse mcResponse = new MailChimpResponse();
    var listId = "xxxxxxxxx";

    return await Task.Run(() =>
    {
        try
        {
            var mailChimpListCollection = mailChimpManager.Members.GetAllAsync(listId).ConfigureAwait(false);

            mcResponse.IsSuccessful = true;
            mcResponse.ReponseMessage = "Success!";
        }
        catch (AggregateException ae)
        {
            mcResponse.IsSuccessful = false;
            mcResponse.ReponseMessage = ae.Message.ToString();
        }

        return mcResponse;
    });

目前填充“var mailChimpListCollection”的行应该失败并抛出异常(我可以通过 Intellisense 看到它)但是它继续尝试而不是陷入 CATCH。这只会使每个调用看起来都成功,即使它不是。我在这里错过了什么?

【问题讨论】:

  • 它不会失败,因为它没有被等待。此外,您不需要Task.Run,但如果您决定需要它,则需要指定一个async 委托并在该委托中使用await 进行调用。
  • @AluanHaddad 是对的,请检查-stackoverflow.com/questions/45131200/…
  • 呃,对不起,我使用了 mailChimpManager.Members.GetAllAsync(listId).Wait(3000);在某一时刻,但一旦我的函数完成,它就再也没有回到我的调用函数 SubscribeEmail 来完成其余的“结果”逻辑。
  • 对 Task.Run() @Aluan 的良好调用 - 使用 await/async 是关于在我们等待 IO 绑定任务(例如您的邮件操作)时不阻塞调用线程。通过使用 Task.Run(),我们将在后台线程上开始工作,这是为了避免 CPU 密集型任务阻塞而要做的事情。

标签: c# asp.net webforms task-parallel-library


【解决方案1】:

根据您的描述,您正尝试根据mailChimpManager.Members.GetAllAsync(listId) 调用的结果从SubscribeEmailAsync 方法返回响应。 由于GetAllAsync 方法是一个异步方法,它不是返回成员列表,而是返回一个跟踪结果检索工作的任务。你真的错过了等待,你根本不需要人工的Task.Run。这里我将如何重写SubscribeEmailAsync 方法:

public async Task<MailChimpResponse> SubscribeEmailAsync()
{
    IMailChimpManager mailChimpManager = new MailChimpManager(ConfigurationManager.AppSettings["testing"]);
    MailChimpResponse mcResponse = new MailChimpResponse();
    var listId = "xxxxxxxxx";

    try
    {
        var mailChimpListCollection = await mailChimpManager.Members.GetAllAsync(listId).ConfigureAwait(false);

        mcResponse.IsSuccessful = true;
        mcResponse.ReponseMessage = "Success!";
    }
    catch (AggregateException ae)
    {
        mcResponse.IsSuccessful = false;
        mcResponse.ReponseMessage = ae.Message.ToString();
    }

    return mcResponse;
}

希望这会有所帮助。

【讨论】:

  • 看起来不错,但我不认为 AggregateException 是你想要的。它将自动展开。除非那是 Mailchimp 抛出的……
  • 我将那部分保留在@Chuck 共享的原始代码中。假设这就是他要找的……
  • 是的,我已经编写了一个示例,该示例说 AggregateException 是返回的方式,但我在进行更新后对其进行了简化。现在一切正常……虽然不是全部,但我正在路上。谢谢大家!
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2012-05-04
  • 2013-12-05
  • 2015-10-24
  • 2011-09-16
相关资源
最近更新 更多