【问题标题】:Why InvalidCastException when awaiting Task-returning method?为什么在等待任务返回方法时出现 InvalidCastException?
【发布时间】:2013-10-10 00:53:44
【问题描述】:

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

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

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

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

    ...完美运行。

    这里的事情是,由于我的一个参数(filedynamic),这将是一个动态操作。并且返回值似乎被动态操作“搞砸了”; CLR 根本无法从上面的代码中推断出该方法是返回 Task 还是 Task&lt;T&gt;(或者我猜是这样)。因此,尝试将结果转换为 INotifyCompletion 实例失败 - 因此出现异常。

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

    【讨论】:

      猜你喜欢
      • 2016-09-27
      • 2013-06-04
      • 1970-01-01
      • 2014-08-05
      • 2018-09-03
      • 1970-01-01
      • 2018-07-31
      • 2014-10-01
      相关资源
      最近更新 更多