【问题标题】:Exception Thrown from Thread Pool Thread shown as Unhandled从线程池线程抛出的异常显示为未处理
【发布时间】:2015-02-18 22:05:41
【问题描述】:

我正在通过以下方法在后台线程池线程上启动一个任务

private async Task LoadCoreMatchDataAsync()
{
    string errorMessage = String.Empty;
    ...
    try
    {
        if (!HasConnection)
            return;

        IProgress<string> progressIndicator = new Progress<string>(LoadProgress);
        EventsCollection = new BindableCollection<Taurus.MatchDetails>(
            await MatchDataService.GetCollectionAsync(
                this.client, progressIndicator, this.token));
        ...
    }
    catch (TimeoutException toe)
    {
        errorMessage = String.Format(
            "Retrieval of the MatchDetails using connection " +
            "\"{0}\" failed with the following TimeoutException: \"{1}\".",
            this.ConnectionString,
            toe.Message);
    }
    catch (OperationCanceledException)
    {
        // Do nothing, cancel silently.
    }

    // Display any errors.
    if (!String.IsNullOrEmpty(errorMessage))
    {
        await dialogManager.ShowDialog<MessageDialogResult>(
            new MessageBoxViewModel("Connection Timeout", errorMessage, mbs));
        HasConnection = false;
    }
}

GetCollectionAsync(...) 方法在哪里

public async Task<BindableCollection<Taurus.MatchDetails>> GetCollectionAsync(
    MongoClient client, IProgress<string> progressIndicator, CancellationToken token)
{
    return await Task.Factory.StartNew<BindableCollection<Taurus.MatchDetails>>(() =>
        {
            ... // Somewhere in here we get a TimeoutException thrown. 
        }, token);
}

问题是,当我调用await MatchDataService.GetCollectionAsync(...) 时,我得到一个预期 TimeoutException,VS2012 抛出“用户代码未处理 TimeoutException”消息,而我显然正在处理异常在“继续”中以正确的方式。如果我继续而不是中断,则确实捕获了异常,并且我收到了预期的错误消息。我只是不确定为什么 VS2012 告诉我异常未处理?

我基本上是在做 Jon Skeets 的答案https://stackoverflow.com/a/19865613/626442 中明确描述的事情。

感谢您的宝贵时间。

【问题讨论】:

  • 如果您使用Task.Run 而不是Task.Factory.StartNew,行为是否会改变?前者通常更合适。
  • 我最终将使用自定义调度程序,所以这就是我没有使用Task.Run 的原因,但你当然是对的。但是,切换它不会有任何区别。
  • 你能在你的GetCollectionAsync 方法中使用try-catch 来测试它吗?并从 catch 块中抛出异常。

标签: c# exception task-parallel-library async-await


【解决方案1】:

您已打开“仅我的代码”(我在您引用的另一个问题的回答中提到了这一点)。调试器表明“用户代码”(您的代码)没有处理异常——这是真的。异常被框架代码捕获并放入任务中。

关闭“仅我的代码”调试器设置(在我看来,这是一个只会引起混乱并且用处非常有限的功能)。

【讨论】:

  • 不客气。它也会导致其他烦人的行为:在调用堆栈中,而不是看到真正的调用堆栈,您会看到它的一部分被 [外部代码] 替换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 2014-08-07
  • 2013-06-16
  • 2010-10-11
  • 2016-10-11
  • 1970-01-01
相关资源
最近更新 更多