【问题标题】:VS2017 doesn't give details for an exception, just crashed with nullVS2017 没有给出异常的详细信息,只是以 null 崩溃
【发布时间】:2017-04-05 03:23:49
【问题描述】:

我正在处理一个 UWP 项目,并且错误呈现给我的方式有些奇怪。不知道是VS2017还是UWP是怎么设置的。

我有一段代码上线并检索 json 内容,有时代码有效,有时无效。当我使用 UWP 社区工具包中的 Expander 控件时它可以工作,而当我想切换到 GridView 时它会失败。当它不起作用时,它会在 HttpClient 的 GetStringAsync 方法上失败。奇怪的行为是发生问题的方法中没有抛出异常,代码实际上将我重定向回来而不给出错误,并且一旦它到达应该具有不为空值的属性,我得到一个空异常。 这就是问题发生的地方:

string httpContent = "";

using (HttpClient httpClient = new HttpClient())
{
    try
    {
        httpContent = await httpClient.GetStringAsync(uri);
    }
    catch (Exception e)
    {
        // TODO: handle errors
        var x = "";
    }
}

这段代码是从视图模型中调用的。它以构造函数开头,RefreshServerKanesWrathDataAsync 是解析 json 的方法。

public CncOnlinePageViewModel()
{
    cnconline = new CncOnline();
    cnconline.RefreshServerKanesWrathDataAsync();
}

当我到达 GetStringAsync 时,代码只是像什么都没发生一样返回到构造函数,但是该方法从未完成,它只是退出到构造函数,因此无法使用数据更新可观察集合。然后我得到一个空异常。

我想用 VS2015 测试一下,但是我更新了一些显然只有 VS2017 支持的控件,所以我无法在其他版本中运行代码。

在此问题之前,我还遇到了代码问题,我尝试在不使用令牌的情况下访问目录中的文件。行为完全相同,代码并没有告诉我我无权访问我想要读取的目录,它只是将我从方法中抛出回到调用读取目录的位置.就像当前的问题一样,我会遇到一个空异常,这不是主要问题所在。

我将 Template10 和 UWP 社区工具包添加到项目中,如果这很重要的话。

【问题讨论】:

    标签: c# uwp windows-community-toolkit


    【解决方案1】:

    除非您愿意提供回调,否则不应从构造函数调用异步方法。

    public CncOnlinePageViewModel()
    {
        cnconline = new CncOnline();
        var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task<string>
        t.ContinueWith(OnCompleted);
    }
    
    private void OnCompleted(Task<string> task)
    {
        if (task.IsFaulted)
        {
            // Check error
            var exception = task.Exception;
        }
        else if (task.IsCanceled)
        {
            // User hit cancel?
        }
        else
        {
            // All good!
            var result = task.Result;
        }
    }
    

    这是一个示例,其中RefreshServerKanesWrathDataAsync() 只返回Task(不是Task&lt;result&gt;

    public CncOnlinePageViewModel()
    {
        cnconline = new CncOnline();
        var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task
        t.ContinueWith(OnCompleted);
    }
    
    private void OnCompleted(Task task)
    {
        if (task.IsFaulted)
        {
            // Check error
            var exception = task.Exception;
        }
        else if (task.IsCanceled)
        {
            // User hit cancel?
        }
        else
        {
            // All good!
        }
    }
    

    附带说明,您可能还需要在引发任何异常时中断 Visual Studio 2017。在 VS2017 中,转到 Debug->Windows->Exception Settings 并确保 Common Language Runtime Exceptions 有检查。如果它有一个已填充的框,请单击该框,直到它变成复选标记。

    另外...,当任何任务有未观察到的异常时,您可以利用引发的事件。你可以在App.xaml.cs的构造函数中这样做

    public App()
    {
       TaskScheduler.UnobservedTaskException += OnUnobservedException;
    }
    
    private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
    {
       // Put break point here.
       var ex = e.Exception;
    
       // This will keep your app alive, but only do it if it's safe to continue.
       e.SetObserved(); 
    }
    

    【讨论】:

    • 我进行了更改,但 OnCompleted 有一个红色波浪线,并且错误是说“参数 1:无法从 '方法组' 转换为 'Action'” 关于如何做的任何建议?
    • 确保您的类型匹配。 private void OnCompleted(Task&lt;RETURNTYPE&gt; task) 匹配 public Task&lt;RETURNTYPE&gt; RefreshServerKanesWrathDataAsync() 的返回类型
    • 我添加了一个示例,其中您的方法仅返回 Task 而不是 Task&lt;result&gt;
    • 无法正常工作。 RefreshServerKanesWrathDataAsync() 是一个 Task 方法,它只是获取一些在线数据并用它填充一个集合。我添加了这个签名“private void onCompleted(Task task)”来匹配 Refresh 方法返回的内容,就像你建议的那样,并且返回了 null 异常。
    • OnCompleted(Task task)的第一行放一个断点...会发生什么?会被击中吗?
    猜你喜欢
    • 2016-03-19
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 2012-11-26
    • 2011-03-20
    • 2017-09-15
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多