等待线程在c#/ Xamarin完成

时间:2014-10-04 20:24:27

标签: c# ios multithreading xamarin

我在这里遇到了一件棘手的事情。我正在开发一个带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()被触发,异步任务完成后,这将起作用。但是当数据完全到达时我需要触发重载。你明白我的问题吗?谢谢你的帮助。

2 个答案:

答案 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完成的第二个视图,这里没什么好看的