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

问题描述 投票:0回答:1

(问题的真正标题应该是“为什么我会收到‘无法将类型为‘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();

...它运行完美。为什么?

c# .net async-await c#-5.0
1个回答
13
投票

有时事实证明,我在将问题发布到此处时设法找到了问题的答案。我想我会分享它来避免其他人头痛......

问题源于我对

dynamic
的使用,或者更确切地说,(在我看来)
dynamic
迄今为止在 C#/.NET 中的工作方式略有限制和破坏。如果我像这样改写我的代码:

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

...它运行完美。

这里的问题是,由于我的参数之一(

file
)是
dynamic
,所以这将是一个动态操作。并且返回值似乎在某种程度上因动态操作而“混乱”; CLR 根本无法从上面的代码中推断出该方法是否返回
Task
还是
Task<T>
(或者我猜是这样)。因此,它无法尝试将结果转换为
INotifyCompletion
实例 - 因此,出现异常。

非常感谢很多,微软。 ;)
(我认为这里的主要问题是异常消息非常不清楚,在我看来......)

© www.soinside.com 2019 - 2024. All rights reserved.