C# 在可移植类库中使用await HttpClient.GetAsync时发生异常
我有可移植类库(net40+sl4+win8+wp71),代码:C# 在可移植类库中使用await HttpClient.GetAsync时发生异常,c#,portable-class-library,async-await,C#,Portable Class Library,Async Await,我有可移植类库(net40+sl4+win8+wp71),代码: 公共静态异步任务GetFeeds() { 尝试 { 字符串数据; 使用(HttpMessageHandler=newHttpClientHandler()) { 使用(HttpClient HttpClient=新HttpClient(处理程序)) { data=await httpClient.GetStringAsync(FeedsUrl+Guid.NewGuid()).ConfigureAwait(false); }
公共静态异步任务GetFeeds()
{
尝试
{
字符串数据;
使用(HttpMessageHandler=newHttpClientHandler())
{
使用(HttpClient HttpClient=新HttpClient(处理程序))
{
data=await httpClient.GetStringAsync(FeedsUrl+Guid.NewGuid()).ConfigureAwait(false);
}
}
如果(数据!=null)
{
//...
}
返回null;
}
抓住
{
返回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()
框架版本:v4.0.30319
描述:由于未处理的异常,进程已终止。
异常信息:System.Runtime.InteropServices.COMException
堆栈:
在System.Runtime.CompilerServices.AsyncMethodBuilderCore.b__1(System.Object)中
在System.Threading.QueueUserWorkItemCallback.WaitCallback_上下文(System.Object)中
位于System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object,布尔值)
在System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object,布尔值)
位于System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()处
在System.Threading.ThreadPoolWorkQueue.Dispatch()中
在System.Threading.\u ThreadPoolWaitCallback.PerformWaitCallback()中
编辑:如果我注释行“data=await httpClient.GetStringAsync”,它将毫无例外地工作
在第二次发射时,它总是有效的
有什么建议吗?只是猜测,但看起来您遇到了一个未处理的异常,可能是在异步void方法中。当wait调用恢复时,它会抛出异常,但由于它刚刚从wait中恢复,因此调用堆栈不会反映代码中发生故障的位置
我建议将所有异步void方法的主体包装在try/catch块中,该块将报告异常以及异常在代码中发生的位置。这将有助于找出问题所在。一旦出现异常,查看它的HResult属性也可能会有所帮助。这些包具有特定于框架的实现。您可能遇到问题,因为您没有从Win8应用程序中引用特定于框架的程序集 您能否尝试从应用程序中引用Nuget包,看看它是否解决了问题?Nuget不会在堆栈上安装包,因此当您创建使用另一个Nuget包的类库时,需要手动将该Nuget包添加到引用该类库的项目中
当类库通过包依赖项打包为nupkg时,这种情况会很明显,但当您使用项目或二进制引用时,您需要自己完成。我已经找到了答案。我使用MVVM Light,所以我有ViewModelLocator,代码为:
公共ViewModelLocator() { ServiceLocator.SetLocatorProvider(()=>SimpleIoc.Default); SimpleIoc.Default.Register(true); } 因此,当我删除立即创建的模型时,它停止崩溃:
SimpleIoc.Default.Register(/*true*/);
我不知道为什么,但我认为这是因为MVVM Light在Microsoft.Bcl、Microsoft.Bcl.Async或Microsoft.Net.Http上存在一些问题
希望这能帮助某些人,例如只是好奇,为什么在win 8下使用.net 4.0-我想win 8默认有4.5,不是吗?@Isantipov Portable类库意味着它是一个可以从不同版本的框架中使用的库。@svick完全正确尝试捕获异常并查看详细信息…@PeterRitchie,正如您在上面的代码中所看到的,我在该方法中使用try/catch我忘了提到它是在线发生的“data=wait-httpClient.GetStringAsync”。因此,如果您对它进行注释,那么它将正常工作。
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()
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>(true);
}
SimpleIoc.Default.Register<MainViewModel>(/*true*/);