如何在同步函数中调用异步函数?

时间:2018-10-08 13:55:28

标签: xamarin xamarin.android

我希望来自 async 函数的数据作为列表返回,该列表将在同步函数内部分配一个列表。我在xamarin android的Fragment的OnCreateView方法中调用异步函数,该方法返回一个列表。当 async 方法转到并获取数据时,它将进入等待模式。当它等待数据返回时,它退出功能并在调用它的同步方法的代码行下面读取。当 async 函数无法返回列表时。这导致我的活动列表为空,并且没有显示数据。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using OSDAMobileModel;
using System.Net.Http;
using Newtonsoft.Json;
using System.Threading.Tasks;
using System.Collections;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace OSDAMobileApp
{
    public class CheckInFragment : Fragment
    {
        List<Route> lstRoute = new List<Route>();
        public override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);


        }

        public  override View  OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {

            var view = inflater.Inflate(Resource.Layout.SelectRoute, container, false);
            ListView routesListView = view.FindViewById<ListView>(Resource.Id.ListView);
            List<Route> routeslst = lstRoute;
             OnAppearing();

            routesListView.Adapter = new CustomListAdapter(lstRoute);         


          return view;
        }


        protected async Task<List<Route>> OnAppearing()
        //protected  List<Route> OnAppearing()
        {
            SetupFiles setupFiles = new SetupFiles();
            //PRPMaster prpMaster = new PRPMaster();
            var prpDetails = await setupFiles.LoadTextAsync("PRPDetails.txt");

            PRPMaster prpMaster = JsonConvert.DeserializeObject<PRPMaster>(prpDetails);

            foreach (var item in prpMaster.PRPDetails)
            {
                lstRoute.Add(item.Route);
            }
           return lstRoute;

        }


    }
}

1 个答案:

答案 0 :(得分:0)

我建议您直接在async函数中修改列表,然后通过调用以下内容将更改通知适配器:

RunOnUiThread(() => routesListView.Adapter.NotifyDataSetChanged());

您将OnAppearing称为Task.Run(() => OnAppearing());

所以它最终会像:

ListView routesListView;
List<Route> lstRoute = new List<Route>();

...

public  override View  OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    var view = inflater.Inflate(Resource.Layout.SelectRoute, container, false);
    routesListView = view.FindViewById<ListView>(Resource.Id.ListView);

    routesListView.Adapter = new CustomListAdapter(lstRoute);         

    Task.Run(() => OnAppearing());

    return view;
}

...

protected async Task OnAppearing()
{
    SetupFiles setupFiles = new SetupFiles();
    //PRPMaster prpMaster = new PRPMaster();
    var prpDetails = await setupFiles.LoadTextAsync("PRPDetails.txt");

    PRPMaster prpMaster = JsonConvert.DeserializeObject<PRPMaster>(prpDetails);

    foreach (var item in prpMaster.PRPDetails)
    {
        lstRoute.Add(item.Route);
    }

    // This is necessary for the adapter to update its data
    RunOnUiThread(() => routesListView.Adapter.NotifyDataSetChanged());
}

HIH