线程问题 - Web服务完成之前的UI更新

时间:2012-03-03 13:58:29

标签: c# multithreading xamarin.android

我搜索了如何修复的示例 下面的问题,但似乎无法找到我需要的东西,它开始了 开车送我便盆!

基本上,我有一个竞争条件,即web服务正在完成 在返回UI之后,UI不显示任何内容 一点都不。

这是代码。 webservice确实获得了正确的数据 这一切的痛苦! generateNewScreen方法的结果是 单击ListView区域上的某些文本。

调用例程

private void generateNewScreen(int t)
{
    string[] races = new string[] { };
    View currentview = FindViewById<View>(Resource.Id.relLayout);
    TextView text = FindViewById<TextView>(Resource.Id.textTitle);
    ListView listView = FindViewById<ListView>(Resource.Id.listView);
    ImageView image = FindViewById<ImageView>(Resource.Id.imgBack);
    image.Visibility = ViewStates.Visible;

    Console.WriteLine("t = {0}, addFactor = {1}", t,addFactor);

    switch (addFactor)
    {
        case 0: 
            switch (t)
            {
                case 0: races =listviewInfo(Resource.Array.RaceTracks,
                    Resource.Drawable.Back_RaceHorsePlace, Resource.String.Tracks);
                    addFactor = 10;
                    break;

                case 1: List<string> 
                    race = new List<string>();                                                  
                    currentview.SetBackgroundDrawable(Resources.GetDrawable(Resource.Drawable.Back_BobMoore));
                    text.Text = Resources.GetString(Resource.String.ComingSoon);
                    webservice_user getRace = new webservice_user();
                    race = getRace.getUpcomingRaces("RP");
                    races = race.ToArray();
                    addFactor = 20;
                    break;
            }

            if (t < 6 || t == 7)
                listView.Adapter = new ArrayAdapter<string>(this, Resource.Layout.listview_layout, races);
            break;
    }
}

web服务

private string rTrack;

public List<string> getUpcomingRaces(string track)
{
    List<string> f = new List<string>();
    rTrack = track;
    getUpcomingRacesCallBack((list) =>
    {
        f = list;
    });
    return f;
}

private void getUpcomingRacesCallBack(Action<List&lt;string>> callback)
{
    List<string> f = new List<string>();

    if (checkForNetwork(true) != true)
    {
        f.Add("No network available");
        callback(f);
    }
    else
    {
        List<POHWS.webservice.UpcomingRaces> tableData = new List<POHWS.webservice.UpcomingRaces>();
        POHWS.webservice.Service1 Service3 = new POHWS.webservice.Service1();
        try
        {
            Service3.BeginGetUpcomingRacesList(rTrack, delegate(IAsyncResult iar)
            {
                tableData = Service3.EndGetUpcomingRacesList(iar).ToList();
                Android.App.Application.SynchronizationContext.Post(delegate
                {
                    if (tableData.Count == 0)
                    {
                        f.Add("No Upcoming Races Found within the next 7 days");
                        callback(f);
                    }
                    else
                    {
                        for (int i = 0; i < tableData.Count;++i)
                            f.Add(tableData[i].PostTime);
                        callback(f);
                    }
                }, null);
            }, null);
        }
        catch (Exception oe)
        {
            f.Add(oe.ToString());
            callback(f);
        }
    }
}

是否可以停止UI或延迟更新,直到webservice 已经做了它需要的东西?我已经尝试了很多东西,但没有给出任何东西。

1 个答案:

答案 0 :(得分:1)

这里的问题是getUpcomingRaces()的行为就好像对getUpcomingRacesCallBack()的调用是同步的,并立即返回列表。因为lambda在返回语句之前不太可能被触发,所以它总是返回空列表。

我建议重新构建代码,使其仅在返回后才会在列表中执行,类似于您使用getUpcomingRacesCallBack()方法采用的方法,该方法接收Action<List<string>>

如果有帮助,我有一个示例项目available here,展示如何使用此模式。我还有一个post here,讨论了在UI线程上完成工作的一些不同方法,以防你最终走上使调用同步的路径。