(问题的真正标题应该是为什么我得到无法投类型的对象System.Runtime.CompilerServices.TaskAwaiter`1 [System.Runtime.CompilerServices.VoidTaskResult]'输入'系统。 Runtime.CompilerServices.INotifyCompletion',但不幸的是,这是太长了计算器:)
(The real title of the question should be "Why do I get a 'Unable to cast object of type 'System.Runtime.CompilerServices.TaskAwaiter`1[System.Runtime.CompilerServices.VoidTaskResult]' to type 'System.Runtime.CompilerServices.INotifyCompletion'", but unfortunately this is too long for StackOverflow. :)
您好,
我试图时变得非常奇特的问题接踵而至
我的一个方法的执行。调用code如下(节选):
I'm getting really peculiar problems when trying to await
the execution of a method of mine. The calling code looks like this (excerpt):
private async Task DownloadAddonFileAsync(dynamic addon, dynamic file, string targetFolder)
{
// ...
await DownloadFileAsync(file, targetFolder, uri);
在DownloadFileAsync看起来是这样的:
The DownloadFileAsync looks like this:
protected async Task DownloadFileAsync(dynamic file, string targetFolder, string uri)
{
// ...
var fileBytes = await AppLoaderRestClient.GetAsync<byte[]>(uri);
在AppLoaderRestClient.GetAsync(),反过来,看起来是这样的:
The AppLoaderRestClient.GetAsync(), in turn, looks like this:
public static async Task<T> GetAsync<T>(string uri)
{
// ...
if (typeof (T) == typeof (byte[]))
{
var result = await webClient.DownloadDataTaskAsync(uri);
return (T) (object) result;
}
所以,其实是有链的任务在这里 - 内部任务将是一个任务,然后将被传播到调用者,并将其转换为一个任务(即任务无的结果)。我presume这可能手头会造成这个问题?
So, there is actually a chain of Tasks here - the "inner" Task will be a Task, which will then be propagated up to the caller, and converted to a Task (i.e. a Task without a result). I presume this could be causing the issue at hand?
如果我更改最外面的code到这一点:
If I change the outermost code to this:
var task = DownloadFileAsync(file, targetFolder, uri);
task.Wait();
...它完美的作品。为什么呢?
...it works flawlessly. Why?
由于它有时会证明,我设法找到了问题的答案,而在这里张贴。想我会分享它救别人头痛...
As it sometimes turns out, I managed to find out the answer to the question while posting it here. Thought I'd share it to save someone else from headache...
这是我使用的动态,或者更确切地说,问题的根源时,(在我看来)轻度受限和破碎的方式动态作品在C#/。NET的呢。如果我重新整理我的code是这样的:
The problem stems from my use of dynamic, or rather, the (in my opinion) slightly limited and broken way dynamic works in C#/.NET as of yet. If I rephrase my code like this:
await (Task)DownloadFileAsync(file, targetFolder, uri);
...它完美的作品。
...it works flawlessly.
下面的事情是,因为我的参数之一(文件
是动态的),这将是一个动态操作。和返回值似乎被某种方式从动态操作搞砸了; CLR的是根本无法从code来推断上述是否该方法返回工作
或任务&LT; T&GT;
(左右我猜)。因此,它失败尝试的结果强制转换为INotifyCompletion实例 - 因此,除了
The thing here is that since one of my parameters (file
is dynamic), this will be a dynamic operation. And return values seem to be somehow "messed up" from dynamic operations; the CLR is simply unable to deduce from the code above whether the method returns Task
or Task<T>
(or so I guess). It therefore fails trying to cast the result to an INotifyCompletion instance - hence, the exception.
感谢的很多的微软。 ;) (我觉得这里的主要问题是,异常消息是很清楚,在我看来...)
Thanks a lot, Microsoft. ;) (I think the main problem here is that the exception message was very unclear, in my opinion...)