我正在尝试从Parse(使用c#的xamarin.ios)检索用户数据。我正在等待使用异步方法。我的挑战是,每当我导航到应用程序中的tableView时,应该填充有问题的用户数据,表格总是空的。
我想等到结果返回后再继续代码的其他部分。我试图使用ContinueWith()函数但是经常遇到构建错误 -
Cannot implicitly convert type 'void' to System.Collections.Generic.IEnumerable<Parse.ParseObject>
我的问题:
这是我目前的实施:
public async void retrieveData(string username)
{
try
{
this.requests.ClearRequests();
refreshed = false;
var query = ParseObject.GetQuery("Requests").WhereEqualTo("username", username);
IEnumerable<ParseObject> results = await query.FindAsync().ContinueWith(t =>{
if(results != null)
{
foreach(ParseObject parseObject in results)
{
UserRequest request = new UserRequest();
request.objectId = parseObject.ObjectId;
request.make = parseObject.Get<string> ("item1");
request.model = parseObject.Get<string> ("item2");
request.year = parseObject.Get<string> ("item3");
request.userName = parseObject.Get<string> ("username");
this.requests.addRequest (request);
}
refreshed = true;
}
});
}
catch(ParseException e) {
Console.WriteLine (e.Message + e.StackTrace);
}
}
答案 0 :(得分:1)
您不应该需要ContinueWith
...这就是await
应该处理的内容。
await
等待Task
,然后使用正确的返回类型返回结果。 ContinueWith
会返回Task
,因此您必须从任务中抓取Result
才能使其可用。
有关此类事情的更多信息,您可以查看Difference between await and ContinueWith
你可以尝试这样的事情。
public async void retrieveData(string username, )
{
try
{
this.requests.ClearRequests();
refreshed = false;
var query = ParseObject.GetQuery("Requests").WhereEqualTo("username", username);
IEnumerable<ParseObject> results = await query.FindAsync();
if(results != null)
{
foreach(ParseObject parseObject in results)
{
UserRequest request = new UserRequest();
request.objectId = parseObject.ObjectId;
request.make = parseObject.Get<string> ("item1");
request.model = parseObject.Get<string> ("item2");
request.year = parseObject.Get<string> ("item3");
request.userName = parseObject.Get<string> ("username");
this.requests.addRequest (request);
}
refreshed = true;
}
//This is your refresh method for your TableView
this.RefreshTableView();
//or, if in iOS
NSNotificationCenter.DefaultCenter.PostNotificationName("resultsRetrieved", null);
}
catch(ParseException e) {
Console.WriteLine (e.Message + e.StackTrace);
}
}
要在tableView
中显示结果,我建议将tableView
的刷新移动到在检索和解析results
后同步触发的单独方法。这通过上面的this.RefreshTableView()
调用显示。
如果在iOS
Xamarin
上post
,则另一个选项是notification
NSNotificationCenter
PostNotificationName
(the Xamarin documentation for which is here)。使用上面看到的ViewControllers
部分,然后在notificationToken
中添加一个您希望依赖于数据的观察者。这样做如下:
制作一个 NSObject notificationToken;
对象:
ViewDidLoad
然后在您的设置方法中(您可以将其置于void Setup ()
{
notificationToken = NSNotificationCenter.DefaultCenter.AddObserver ("resultsRetrieved", RefreshData);
}
内):
RefeshData
制作void RefreshData (NSString notifString)
{
this.tableView.ReloadData();
}
方法:
void Teardown ()
{
NSNotificationCenter.DefaultCenter.RemoveObserver (notificationToken);
}
然后,确保在拆除课程时丢弃通知观察员
findAll
答案 1 :(得分:0)
我有一个类似的问题,所以开始使用回调。我在Xamarin.Android中使用它们,非常确定它们可以在Xamarin.iOS中使用。
启动任务方法的方法 - 注意我将此类的方法作为参数传递
private async void updatedData()
{
await Utils.DataTasks.getNewLiveTips(populateTipsList);
}
从服务器调用数据的方法
public class DataTasks
{
public static async Task getAllData(Action<IEnumerable<ParseObjects>> callback) {
var query = new ParseQuery<ParseObjects>().OrderByDescending("updatedAt").Limit(5);
IEnumerable<ParseObjects> parseTips = await query.FindAsync();
foreach (var tip in parseTips)
{
// Save data to DB if needed
}
callback(parseTips);
}
我在第一个实例中作为参数传递的方法现在称为
private void populateTipsList(IEnumerable<ParseObjects> results)
{
mAdapter = new TipAdapter(this.Activity, results);
mRecyclerView.SetAdapter(mAdapter);
refresher.Refreshing = false;
}