0

我正在开发一个 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 社区工具包,如果这很重要的话。

4

1 回答 1

3

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

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(not Task<result>)的示例

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(); 
}
于 2017-04-05T03:42:48.103 回答