I have the following code:
string commandText = await _client
.GetCommandTextAsync("Products", x.ProductName == "Chai");
The second parameter (x.ProductName == "Chai") contains a dynamic clause (x.ProductName), so the resulting expression is also dynamic. When this code is executed on .NET 4.0, sometimes it throws the following exception:
System.InvalidCastException Unable to cast object of type 'System.Runtime.CompilerServices.TaskAwaiter`1[System.String]' to type 'System.Runtime.CompilerServices.INotifyCompletion'.
The exception is not thrown if I explicitly case the method result to Task:
string commandText = await (Task<string>)_client
.GetCommandTextAsync("Products", x.ProductName == "Chai");
Is there a more elegant way to resolve this problem (without casting every single line of code that awaits for a dynamic result), or is this a known problem with using TPL on .NET 4.0.
I haven't experienced this on .NET 4.5.
Here is a theory:
According to the TaskAwaiter definition:
[HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
public struct TaskAwaiter : ICriticalNotifyCompletion, INotifyCompletion
it seems that TaskAwaiter is an INotifyCompletion. You said you have dynamic clause in your code. As MS states dynamic objects are mostly behaves like object. Thus casting is required in the code which is handled by run-time or compiler.
You also stated that platform is Xamarin iOS. Which possibly utilizing HostProtectionAttribute for example to block usage of some classes or etc.
The TaskAwaiter implementation is marked with SecurityAction.LinkDemand and again if we check MSDN it says:
...
LinkDemand (do not use in the .NET Framework 4)
...
So conclusion is: The platform which code is running, is lacking security implementations required by Host Protection and methods are not invoked (while security is not working properly) Casting is one of "secure" operation thus this type of runtime casting fails.
if you explicitly cast like you did, there is no problem because compiler does not add the "buggy" code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With