为什么在等待任务返回方法时出现InvalidCastException?

时间:2013-10-03 10:50:52

标签: c# .net async-await c#-5.0

(问题的真正标题应该是“为什么我得到'无法将'System.Runtime.CompilerServices.TaskAwaiter`1 [System.Runtime.CompilerServices.VoidTaskResult]'类型的对象强制转换为'System'。 Runtime.CompilerServices.INotifyCompletion'“,但不幸的是,这对于StackOverflow来说太长了。:)

您好,

在尝试await执行我的方法时,我遇到了一些特殊的问题。调用代码如下所示(摘录):

    private async Task DownloadAddonFileAsync(dynamic addon, dynamic file, string targetFolder)
    {
        // ...
        await DownloadFileAsync(file, targetFolder, uri);

DownloadFileAsync如下所示:

    protected async Task DownloadFileAsync(dynamic file, string targetFolder, string uri)
    {
        // ...
        var fileBytes = await AppLoaderRestClient.GetAsync<byte[]>(uri);

AppLoaderRestClient.GetAsync()反过来看起来像这样:

    public static async Task<T> GetAsync<T>(string uri)
    {
        // ...
        if (typeof (T) == typeof (byte[]))
        {
            var result = await webClient.DownloadDataTaskAsync(uri);
            return (T) (object) result;
        }

所以,这里实际上有一个任务 - “内部”任务将是一个任务,然后将其传播到调用者,并转换为任务(即任务)没有结果)。我认为这可能导致手头的问题?

如果我将最外面的代码更改为:

        var task = DownloadFileAsync(file, targetFolder, uri);
        task.Wait();

......它完美无瑕。为什么呢?

1 个答案:

答案 0 :(得分:10)

有时候结果显示,我在这里发布时找到了问题的答案。以为我会分享它以免其他人头痛......

问题源于我使用动态,或者更确切地说,(在我看来)C#/ .NET中的动态作品略有限制和破碎。如果我改写我的代码:

await (Task)DownloadFileAsync(file, targetFolder, uri);

......它完美无缺。

这里的事情是,由于我的一个参数(file是动态的),这将是一个动态操作。并且返回值似乎以某种方式“混乱”来自动态操作; CLR根本无法从上面的代码中推断出该方法是返回Task还是Task<T>(或者我猜)。因此,它无法尝试将结果转换为INotifyCompletion实例 - 因此,例外。

感谢 lot ,Microsoft。 ;)
(我认为这里的主要问题是异常信息非常不清楚,在我看来......)