在便携式类库中使用 await HttpClient.GetAsync 时出现异常

3
我有一个可移植类库(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
1
@Isantipov 便携式类库意味着它可以从各种版本的框架中使用。 - svick
@svick 是完全正确的。 - KondraT
尝试捕获异常并查看详细信息... - Peter Ritchie
@PeterRitchie,正如您在上面的代码中所看到的,我在该方法中使用了try/catch。 - KondraT
3个回答

2
这些软件包具有特定于框架的实现。您可能会遇到问题,因为您的Win8应用程序没有引用特定于框架的程序集。
您可以尝试从应用程序中引用Nuget软件包,看看是否解决了问题?Nuget不会安装堆栈上方的软件包,因此,当您创建一个使用另一个Nuget软件包的类库时,您需要手动将该Nuget软件包添加到引用该类库的项目中。
当类库作为nupkg通过软件包依赖项打包时,这会自动发生,但是当您使用项目或二进制引用时,您需要自己做。

1

猜测一下,看起来你正在遇到一个异常,而你没有处理它,可能是在一个异步的void方法中。当await调用恢复时,它会抛出异常,但由于它刚刚从await中恢复,调用堆栈并不反映故障发生的代码位置。

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


我忘了提到它发生在“data = await httpClient.GetStringAsync”这一行。因此,如果您将其注释掉,那么它将正常工作。 - KondraT

1
我已经想通了。我使用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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接