Summary :我想在构造函数中调用异步方法 . 这可能吗?
Details :我有一个名为 getwritings()
的方法来解析JSON数据 . 如果我只是在一个 async
方法中调用 getwritings()
并将 await
放在它的左边,那么一切正常 . 但是,当我在我的页面中创建 LongListView
并尝试填充它时,我发现 getWritings()
令人惊讶地返回 null
并且 LongListView
为空 .
为了解决这个问题,我尝试将 getWritings()
的返回类型更改为 Task<List<Writing>>
,然后通过 getWritings().Result
在构造函数中检索结果 . 然而,这样做最终 blocking the UI thread.
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;
}
}
6 回答
你可以试试AsyncMVVM .
Page2.xaml:
Page2.xaml.cs:
ViewModel2.cs:
尝试替换这个:
有了这个
简单地说,指的是Stephen Cleary https://stackoverflow.com/a/23051370/267000
您的创建页面应该在构造函数中创建任务,您应该将这些任务声明为类成员或将其放在任务池中 .
在这些任务期间获取您的数据,但是代码中应该等待这些任务,即在一些UI操作上,即Ok Click等 .
我在WP中开发了这样的应用程序,我们在启动时创建了一大堆任务 .
最好的解决方案是确认下载和设计的异步性 .
换句话说,在下载数据时确定应用程序的外观 . 让页面构造器设置该视图,然后开始下载 . 下载完成后,更新页面以显示数据 .
我在asynchronous constructors上有一篇博文,你会发现它很有用 . 还有一些MSDN文章;一个在asynchronous data-binding(如果你正在使用MVVM)而另一个在asynchronous best practices上(即你应该避免
async void
) .我想分享一种我一直用来解决这些问题的模式 . 我觉得它运作得相当好 . 当然,它只有在你可以控制调用构造函数的情况下才有效 . 以下示例
基本上我们所做的是将构造函数设为私有,并创建我们自己的公共静态异步方法,该方法负责创建MyClass的实例 . 通过使构造函数私有并将静态方法保持在同一个类中,我们确保没有人可以“无意中”创建此类的实例而无需调用正确的初始化方法 . 围绕对象创建的所有逻辑仍包含在类中(仅在静态方法中) .
在当前场景中实现它看起来像:
而不是做
你会做的
你也可以这样做: