我在这里遇到了一件棘手的事情。我正在开发一个带Xamarin的iOS应用程序。 (我想如果你不了解xamarin但c#你也可能知道答案 - 它基本上是一个线程问题!)我有一个包含几个条目的表,当用户点击其中一个条目时,它需要我从Web服务加载数据。然后,该数据显示在第二个表中,显示了我推送到的另一个视图。问题是:在用户单击表条目的确切时刻,触发推送到另一个视图,同时触发viewDidLoad(),我在其中设置表条目。但现在有时会发生前一个视图中的异步网络任务没有完成,这使得表空。总结一下:在异步网络请求完成其工作后,我需要在View i push to上触发Table.Reload()。我怎么做?我真的被困在这里了。以下是我的代码的一些细节:
第一视图控制器
public async override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
//Sends the titles, subtitles, and the Headline to the DetailView
base.PrepareForSegue (segue, sender);
...
Task<String[,]> getJsonDataTask = SearchRequest.searchRequest (text, "Calendar");
arrayContent = await getJsonDataTask;
...
for (int i = 0; i < 50; i++) {
tableItems.Add(arrayContent [1, i]);
tableSubtitles.Add( arrayContent [5,i]);
Dates.Add(tableItems[i]);
Descriptions.Add (tableSubtitles [i]);
}
var calendarDetailController = segue.DestinationViewController as CalendarDetailVController;
if (calendarDetailController != null) {
Console.WriteLine ("preparesegue"+Dates.Count);
calendarDetailController.Dates = Dates;
calendarDetailController.Descriptions = Descriptions;
calendarDetailController.TableTitle = text;
calendarDetailController.id = id;
}
所以我在这里开始一个异步线程(它需要通过ansync。导致它的网络请求) 我正在将数据传输到视图控制器。 在
Secound View Controller
我只是获取像
这样的给定数据 public List<String> Dates { get; set; }
public CalendarViewController (IntPtr handle) : base (handle)
{
Dates = new List<String> ();
}
然后我在ViewDidLoad();
中重新加载表数据 public override async void ViewDidAppear (bool animated)
{
base.ViewDidAppear (animated);
//as the resource loading is async. whe need to refresh table here
TableView.ReloadData ();
}
有时,如果此ViewDidLoad()被触发,异步任务完成后,这将起作用。但是当数据完全到达时我需要触发重载。你明白我的问题吗?谢谢你的帮助。
答案 0 :(得分:3)
你如何传递任务而不是任务结果?
变化:
public List<String> Dates { get; set; }
致:
public Task<String[,]> DatesTask{get;set;}
然后在第二个viewcontroller的viewDidAppaer中执行任务:
public override async void ViewDidAppear (bool animated)
{
base.ViewDidAppear (animated);
//as the resource loading is async. whe need to refresh table here
Task.Run (async delegate {
await DatesTask().ContinueWith(() => {
InvokeOnMainThread (delegate {
TableView.ReloadData ();
});
});
});
}
我不建议像ViewDidAppaer这样的方法等待,而是让任务处理你的方法的执行,一旦完成,就让你的tableview刷新。这样你就不会在执行任务时冻结用户界面!
或者如果你真的想在第一个viewcontroller中执行你的任务,你应该在执行PrepareForSegue
之前执行你的任务。
答案 1 :(得分:1)
如果我正确理解了您的问题,您似乎只需要将启动调用的视图中的异步Task
传递给需要await
完成的第二个视图,这里没什么好看的