【问题标题】:Waiting for a thread to finish in c# / Xamarin等待线程在 c#/Xamarin 中完成
【发布时间】:2014-10-04 20:24:26
【问题描述】:

我在这里遇到了一件棘手的事情。我目前正在使用 Xamarin 开发 iOS 应用程序。 (我认为,如果您不了解 xamarin 但 c#,您可能也知道答案 - 它基本上是线程问题!)我有一个包含多个条目的表,当用户单击其中一个条目时,它是必需的我从网络服务加载数据。然后,此数据显示在第二个表中,该表显示了我推送到的另一个视图。问题是:在用户单击表格条目的那一刻,触发了对另一个视图的推送,那里的 viewDidLoad() 也被触发,我在其中设置了表格条目。但是现在有时会出现上一个视图中的异步网络任务没有完成,从而使表为空。总结一下:在异步网络请求完成工作后,我需要在我推送到的视图上触发 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;
        }

所以我在这里启动一个异步线程(它需要通过异步。因为它是一个网络请求) 我正在将数据传输到我推送到的视图控制器。 在

第二个视图控制器

我只是获取给定的数据,例如

    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() 被触发,在异步任务完成后,它会起作用。但是我需要在数据完全到达时触发重新加载。你明白我的问题吗?感谢您的帮助。

【问题讨论】:

  • 如果需要等待它完成,为什么要异步启动它?
  • 因为它是一个网络请求 - 它需要在单独的任务中运行 - 或者不是吗?
  • 好吧,如果不需要,我可以像这样解决它 - 我不想这样做,因为我也在 android 应用程序中使用网络请求功能 - 这会给我一个 NetworkOnMainThreadException在那里。
  • 还有一个异步方法让应用更加流畅——推送动画依然流畅,执行任务时不会卡顿
  • 我不知道是否有一个好方法可以等待单独的方法完成。可以从 ViewDidAppear 方法中加载数据吗?

标签: c# ios multithreading xamarin


【解决方案1】:

你传递你的任务而不是任务的结果怎么样?

变化:

public List<String> Dates { get; set; }

收件人:

public Task<String[,]> DatesTask{get;set;}

然后您在第二个视图控制器的 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 刷新。这样你就不会在执行任务时冻结你的用户界面!

或者如果你真的想在你的第一个视图控制器中执行你的任务,你应该在执行PrepareForSegue之前执行你的任务。

【讨论】:

  • 谢谢!这是一个非常详细的解决方案,而且效果很好!
【解决方案2】:

如果我正确理解了您的问题,您似乎只需将异步 Task 从发起调用的视图传递到需要 await 完成的第二个视图,这里没什么特别的。

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多