3

(问题的真正标题应该是“为什么我会得到一个'无法投射'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();

...它完美无缺。为什么?

4

1 回答 1

13

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

问题源于我对 . 的使用dynamic,或者更确切地说,(在我看来)略微受限和破碎的方式dynamic在 C#/.NET 中仍然有效。如果我这样改写我的代码:

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

...它完美无缺。

这里的问题是,由于我的参数之一(fileis dynamic),这将是一个动态操作。并且返回值似乎被动态操作“搞砸了”;CLR 根本无法从上面的代码中推断出该方法是否返回TaskTask<T>(或者我猜是这样)。因此,它无法尝试将结果转换为INotifyCompletion实例 - 因此出现异常。

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

于 2013-10-03T10:50:52.050 回答