等待具有动态参数的方法时抛出异常(有时)

时间:2014-04-12 17:23:42

标签: c# .net c#-4.0 dynamic task-parallel-library

我有以下代码:

string commandText = await _client
       .GetCommandTextAsync("Products", x.ProductName == "Chai");

第二个参数(x.ProductName ==“Chai”)包含一个动态子句(x.ProductName),因此生成的表达式也是动态的。在.NET 4.0上执行此代码时,有时会抛出以下异常:

  

System.InvalidCastException无法转换类型的对象   输入'System.Runtime.CompilerServices.TaskAwaiter`1 [System.String]'   'System.Runtime.CompilerServices.INotifyCompletion'。

如果我将方法结果明确地说明为Task:

,则不会引发异常
string commandText = await (Task<string>)_client
       .GetCommandTextAsync("Products", x.ProductName == "Chai");

是否有一种更优雅的方法来解决此问题(不会抛出等待动态结果的每一行代码),或者这是在.NET 4.0上使用TPL的已知问题。

我在.NET 4.5上没有遇到过这种情况。

1 个答案:

答案 0 :(得分:3)

这是一个理论:

根据TaskAwaiter定义:

[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public struct TaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion

似乎 TaskAwaiter INotifyCompletion 。你说你的代码中有动态子句。由于MS状态动态对象的行为大多与对象相似。因此,在运行时或编译器处理的代码中需要进行转换。

您还说该平台是Xamarin iOS。例如,可能利用 HostProtectionAttribute 来阻止某些类的使用等。

TaskAwaiter实现标有 SecurityAction.LinkDemand ,如果我们检查MSDN它会说:

...
LinkDemand (do not use in the .NET Framework 4)
...

所以结论是:代码运行的平台缺少Host Protection所需的安全实现,并且没有调用方法(安全性不能正常工作)Casting是&#34; secure&#34;因此这种类型的运行时转换失败。

如果你像你一样明确地投射,那就没有问题,因为编译器没有添加&#34; buggy&#34;代码。