我最近第一次使用async(和.Net 4.5),遇到了一些困惑的问题。我在网上找不到关于 VoidTaskResult
类的太多信息,所以我来这里看看是否有人对发生了什么有什么想法。
我的代码类似于以下内容。显然,这简化了很多。基本思路是调用插件方法,这些方法是异步的。如果它们返回Task
,那么异步调用就没有返回值。如果它们返回Task<>
,则会有返回值。我们事先不知道它们的类型,所以想法是使用反射查看结果的类型(如果类型为Type<>
,则IsGenericType
为真)并使用动态类型获取值。
在我的实际代码中,我通过反射调用插件方法。我认为这不应该影响我看到的行为。
// 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
}
}
对于上面展示的插件方法,这很有效。 IsGenericType
为false(如预期所述)。
然而,如果稍微更改插件方法的声明,IsGenericType
现在返回true,会导致出现问题:
public async Task yada()
{
// stuff
}
当您执行此操作时,object result = dynTask.Result;
这一行会抛出以下异常:
如果深入研究任务对象,它实际上似乎是Type<VoidTaskResult>
。 VoidTaskResult
是 Threading 命名空间中的一个私有类型,几乎没有任何内容。
我尝试更改我的调用代码: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
}
}
这种情况下,“成功”指的是不再抛出异常,但现在结果是 VoidTaskResult
类型,我无法合理地处理它。
我应该补充说明的是,我甚至很难为所有这些问题制定一个真正的问题。也许我的真正问题是像“VoidTaskResult
是什么?”或者“当我动态调用异步方法时为什么会发生这种奇怪的事情?”甚至可能是“如何调用可选异步的插件方法?” 无论如何,我将这个问题公开希望其中一位专家能够解答。
typeof
运算符就已经够糟糕了,但是必须将名称作为文本进行比较对我来说尤其令人恼火)。 - Peter Duniho