【问题标题】:Cannot await 'Model.PersonalInfo'无法等待'Model.PersonalInfo'
【发布时间】:2014-02-17 23:13:38
【问题描述】:

我在 DesignDataService 类中有以下方法

public async Task<T> GetData<T>(T dataObject)
{
    var typeName = typeof(T).Name;    
    switch (typeName)
    {
        case "PersonalInfo":
            var person =  new PersonalInfo
                     {
                     FirstName = "Mickey",
                     LastName = "Mouse" ,
                     Adres = new Address{Country="DLRP"} ,
                };
        return await person;

    }   // end Switch

}   // GetData<T>

如何从 DataService 返回一个新的 PersonalInfo 类?

现在我收到错误 Cannot await 'Model.PersonalInfo'

即使我将返回语句更改如下 return await person as Task; 错误保持不变

【问题讨论】:

  • 你为什么需要等待?,你已经创建了对象,所以我认为没有理由异步运行。

标签: c# asynchronous windows-runtime


【解决方案1】:

即使此函数返回Task,也不需要使用async 关键字。

在这里,您可以简单地使用Task.FromResult

public Task<T> GetData<T>(T dataObject) where T : MyKnownBaseObject
{
    var typeName = typeof(T).Name;    
    switch (typeName)
    {
        case "PersonalInfo":
            var person =  new PersonalInfo
                     {
                     FirstName = "Mickey",
                     LastName = "Mouse" ,
                     Adres = new Address{Country="DLRP"} ,
                };
            return Task.FromResult<T>(person);
            break;
        default:
               return Task.FromResult<T>(default(T));

    }   // end Switch

}   // GetData<T>

这不会将工作委托给另一个线程。如果您有少量不适合并行的工作,则此技术有效,但您仍必须强制方法返回任务以与其他方法兼容。

【讨论】:

  • +1。 @Gooftroop,设计时类型或测试存根通常使用这种方法(Task.FromResultnon-async 实现)。
【解决方案2】:

你混合了两件事。您使用async 注释一个方法以指示编译器您希望能够await 异步操作(在任务中)。

另一方面,返回值是Task。您可以将两者混合使用,但在您的情况下 (async Task&lt;T&gt;),这意味着您正在返回操作的异步承诺,但您也在方法中等待一个结果,这肯定不是您想要的。

【讨论】:

  • 谢谢,我删除了异步并且错误消失了。希望它也适用于实时数据。但那是明天的事了。问候
【解决方案3】:

如果PersonalInfo 的创建预计需要很长时间,您需要将对象的创建添加到任务中并等待。

您的方法似乎没有类型限制,因此要返回 PersonalInfo,您必须从 object 转换为 T

例子:

    public async Task<T> GetData<T>(T dataObject)
    {
        var typeName = typeof(T).Name;
        switch (typeName)
        {
            case "PersonalInfo":
                return await Task<T>.Factory.StartNew(() =>
                {
                    return (T)(object)new PersonalInfo
                    {
                        FirstName = "Mickey",
                        LastName = "Mouse",
                        Adres = new Address { Country = "DLRP" },
                    };
                });
        }
        return default(T);
    }   

【讨论】:

  • 如果方法已经是异步返回任务,就不需要创建另一个任务并等待它,是吗?
  • 刚刚做了一个测试。内部任务不是必需的。您可以简单地返回新的个人信息对象。
  • 根本不需要等待,我的假设是这是一个演示,PersonalInfo的创建需要数据库或WebService调用,否则我不知道为什么需要异步作为对象已创建
  • 即便如此 - 假设 PersonalInfo 对象的构造函数需要 20 秒。您仍然不需要初始化内部任务。因为 void 是异步的,所以整个事情都包装在一个任务中,所以简单地返回个人信息对象就足够了 - 然后你可以等待方法返回的任务。
  • @BenVoigt:我的错,我使用了不正确的术语,但这一点仍然有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
  • 2017-08-19
  • 1970-01-01
相关资源
最近更新 更多