总结:我想在构造函数中调用异步方法。这可能吗?

详细信息:我有一个名为getwritings()的方法,用于解析JSON数据。如果我只是在异步方法中调用getwritings()并将await放在它的左边,那么一切都可以正常工作。然而,当我在我的页面中创建一个LongListView并试图填充它时,我发现getWritings()令人惊讶地返回null, LongListView为空。

为了解决这个问题,我尝试将getWritings()的返回类型更改为Task<List<Writing>>,然后通过getWritings(). result在构造函数中检索结果。然而,这样做最终会阻塞UI线程。

public partial class Page2 : PhoneApplicationPage
{
    List<Writing> writings;

    public Page2()
    {
        InitializeComponent();
        getWritings();
    }

    private async void getWritings()
    {
        string jsonData = await JsonDataManager.GetJsonAsync("1");
        JObject obj = JObject.Parse(jsonData);
        JArray array = (JArray)obj["posts"];

        for (int i = 0; i < array.Count; i++)
        {
            Writing writing = new Writing();
            writing.content = JsonDataManager.JsonParse(array, i, "content");
            writing.date = JsonDataManager.JsonParse(array, i, "date");
            writing.image = JsonDataManager.JsonParse(array, i, "url");
            writing.summary = JsonDataManager.JsonParse(array, i, "excerpt");
            writing.title = JsonDataManager.JsonParse(array, i, "title");

            writings.Add(writing);
        }

        myLongList.ItemsSource = writings;
    }
}

当前回答

你也可以这样做:

Task.Run(() => this.FunctionAsync()).Wait();

注意:要小心线程阻塞!

其他回答

试着替换一下:

myLongList.ItemsSource = writings;

用这个

Dispatcher.BeginInvoke(() => myLongList.ItemsSource = writings);

答案很简单,如果你正在开发一个UWP应用程序,然后将async函数添加到页面的Page_Loaded方法。

简单地说,参考斯蒂芬·克利里https://stackoverflow.com/a/23051370/267000

创建页面时应该在构造函数中创建任务,并且应该将这些任务声明为类成员或将其放入任务池中。

你的数据在这些任务期间被获取,但这些任务应该在代码中等待,即在一些UI操作上,即Ok单击等。

我在WP中开发了这样的应用程序,我们一开始就创建了一大堆任务。

我喜欢的方法是:

// caution: fire and forget
Task.Run(async () => await someAsyncFunc());

最好的解决方案是承认下载的异步性质,并为此进行设计。

换句话说,决定在数据下载时应用程序应该是什么样子。让页面构造函数设置该视图,并开始下载。下载完成后更新页面以显示数据。

我有一篇关于异步构造函数的博客文章,您可能会觉得有用。还有一些MSDN文章;一个是关于异步数据绑定的(如果您使用MVVM),另一个是关于异步最佳实践的(即,您应该避免异步void)。