【问题标题】:Exception using await HttpClient.GetAsync in Portable Class Library在可移植类库中使用 await HttpClient.GetAsync 的异常
【发布时间】:2013-03-13 21:37:41
【问题描述】:

我有带有代码的便携式类库(net40+sl4+win8+wp71):

    public static async Task<Dictionary<string, FeedItem>> GetFeeds()  
    {  
        try
        {
            string data;
            using (HttpMessageHandler handler = new HttpClientHandler())
            {
                using (HttpClient httpClient = new HttpClient(handler))
                {
                    data = await httpClient.GetStringAsync(FeedsUrl + Guid.NewGuid()).ConfigureAwait(false);
                }
            }

            if (data != null)
            {
                //...
            }
            return null;
        }
        catch
        {
            return null;
        }
    }

引用了 Microsoft.Bcl、Microsoft.Bcl.Async 和 Microsoft.Net.Http。

我在 Windows 8 Metro 应用程序中使用这个库。然后我通过VS2012调试应用程序,就可以了。但是当我创建应用程序包并安装它时,应用程序在每次启动时都会崩溃并出现错误:

Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Runtime.InteropServices.COMException
Stack:
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(System.Object)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

编辑:如果我注释行“data = await httpClient.GetStringAsync”,它将毫无例外地工作。

在第二次启动时它始终有效。

有什么建议吗?

【问题讨论】:

  • 只是好奇,你为什么在 win 8 下使用 .net 4.0 - 我想,win 8 默认有 4.5,不是吗?
  • @Isantipov 可移植类库意味着它是一个可以从各种版本的框架中使用的库。
  • @svick 完全正确
  • 尝试捕获异常并查看详细信息...
  • @PeterRitchie 正如您在上面的代码中看到的那样,我在该方法中使用 try/catch

标签: c# portable-class-library async-await


【解决方案1】:

这些包具有特定于框架的实现。您可能会遇到问题,因为您没有从您的 Win8 应用程序中引用特定于框架的程序集。

您能否尝试从您的应用程序中引用 Nuget 包,看看它是否能解决问题? Nuget 不会向上安装包,因此当您创建使用另一个 Nuget 包的类库时,您需要手动将该 Nuget 包添加到引用该类库的项目中。

当类库通过包依赖打包为 nupkg 时,这种情况会透明地发生,但是当您使用项目或二进制引用时,您需要自己做。

【讨论】:

    【解决方案2】:

    只是猜测,但看起来您遇到了一个您没有处理的异常,可能是在 async void 方法中。当 await 调用恢复时,它会抛出异常,但因为它只是从 await 恢复,所以调用堆栈不会反映代码中发生故障的位置。

    我建议将您拥有的任何 async void 方法的主体包装在一个 try/catch 块中,该块将报告异常以及它在您的代码中发生的位置。这应该有助于找出问题所在。一旦遇到异常,查看它的 HResult 属性也可能对此有所帮助。

    【讨论】:

    • 我忘了说它发生在“data = await httpClient.GetStringAsync”这一行。因此,如果您对其发表评论,那么它将正常工作。
    【解决方案3】:

    我想通了。我使用 MVVM Light,所以我有 ViewModelLocator 和代码:

    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
        SimpleIoc.Default.Register<MainViewModel>(true);
    }
    

    因此,当我删除模型的立即创建时,它停止崩溃:

    SimpleIoc.Default.Register<MainViewModel>(/*true*/);
    

    我不知道为什么,但我认为这是因为 MVVM Light 在 Microsoft.Bcl、Microsoft.Bcl.Async 或 Microsoft.Net.Http 方面存在一些问题。

    希望这会对某人有所帮助,例如this question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 2016-10-29
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多