【问题标题】:How to use asynchronous method in constructor when .Result() makes the method hang?当 .Result() 使方法挂起时,如何在构造函数中使用异步方法?
【发布时间】:2019-12-02 14:10:11
【问题描述】:

当页面出现在我的 Xamarin.Forms 项目中时,我调用了一个 AppearingCommand,它最终执行以下 sqlite-net-pcl 行:(我已经有一个机制来应对加载时间)

AppearingCommand = new Command( async() => {
    //...
    var data = await db.Table<PlantCategory>().ToListAsync();
    //...
}

我想把这个方法移到构造函数中,但是我做不到,因为如果同步执行它就会挂起:

ctor() {
    //...
    var data = db.Table<PlantCategory>().ToListAsync().Result;
    //...
}

该行永远不会返回(我猜是因为死锁或其他原因)。 如果我想在构造函数中执行这一行,我还有哪些其他选择?

【问题讨论】:

标签: c# sqlite mvvm xamarin.forms sqlite-net-pcl


【解决方案1】:

简单。不要。

相反,添加一个类似async ValueTask InitAsync() 的构造后方法并使用await 调用它。

您可以将其隐藏在您调用的 static ValueTask&lt;Whatever&gt; CreateAsync(...) 方法后面而不是 new Whatever(...),即

class Whatever {
    private Whatever(...) { ... } // basic ctor
    private async ValueTask InitAsync(...) { ... } // async part of ctor

    public static async ValueTask<Whatever> CreateAsync(...) {
        var obj = new Whatever(...);
        await obj.InitAsync(...);
        return obj;
    }
}

【讨论】:

  • 因为这是 Xamarin.Forms,它使用 .NET 标准。没有ValueTask 2.1 之前的版本。
  • @iSpain17 ValueTask[&lt;T&gt;] 降级为 .NET Standard 1.0 和 .NET 4.5 nuget.org/packages/System.Threading.Tasks.Extensions/4.5.3
  • 酷,谢谢!我设法像这样重构,所以我会接受作为答案。
猜你喜欢
  • 1970-01-01
  • 2014-05-27
  • 2015-05-17
  • 2016-12-05
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
相关资源
最近更新 更多