I've been using async (and .Net 4.5 really) for the first time recently, and I've come across something that has me stumped. There isn't much information about the VoidTaskResult class that I can find on the Net so I came here to see if anyone has any ideas about what is going on.
My code is something like the following. Obviously, this is much simplified. The basic idea is to call plugin methods, which are asyncronous. If they return Task, then there is no return value from the async call. If they return Task<>, then there is. We don't know in advance which type they are, so the idea is to look at the type of the result using reflection (IsGenericType is true if the type is Type<>) and get the value using a dynamic type.
In my real code, I am calling the plugin method via reflection. I don't think this should make a difference to the behaviour I am seeing.
// plugin method
public Task yada()
{
// stuff
}
public async void doYada()
{
Task task = yada();
await task;
if (task.GetType().IsGenericType)
{
dynamic dynTask = task;
object result = dynTask.Result;
// do something with result
}
}
This works good for the plugin method shown above. IsGenericType is false (as expected).
However if you change the declaration of the plugin method ever so slightly, IsGenericType now returns true and stuff breaks:
public async Task yada()
{
// stuff
}
When you do this, the following exception is thrown on the line (object result = dynTask.Result;):
If you dig into the task object, it actually appears to be Type. VoidTaskResult is a private type in the Threading name space with almost nothing in it.
I tried changing my calling code:
public async void doYada()
{
Task task = yada();
await task;
if (task.GetType().IsGenericType)
{
object result = task.GetType().GetProperty("Result").GetMethod.Invoke(task, new object[] { });
// do something with result
}
}
This "succeeds" in the sense that it no longer throws, but now result is of the type "VoidTaskResult" which I cannot sensibly do anything with.
I should add that I'm having a hard time even formulating a real question for all this. Maybe my real question is something like "What is VoidTaskResult?", or "Why does this weird thing happen when I call an async method dynamically?" or possibly even "How do you call plugin methods that are optionally asyncronous?" In any case, I am putting this out there in the hope that one of the gurus will be able to shed some light.