下载数据时在MonoTouch中显示微调器

时间:2013-04-16 20:10:19

标签: c# iphone ios xamarin.ios xamarin

所以在我的应用程序中,我有一个按钮,它与一个lib进行对话,从互联网上下载一些数据并对其进行过滤。当应用程序执行此操作时,屏幕会冻结,并向用户显示应用程序崩溃的情况。但事实并非如此,因为它下载了数据。

这是我的代码:

GetDetailsBtn.TouchUpInside += (sender, e) => {

    var defaults = NSUserDefaults.StandardUserDefaults;

    if (RefNr.Text != string.Empty && RefNr.Text != null) {

        FilteredDataRef = _FetchingData.getTrackTraceData (defaults.StringForKey ("SecurityToken"), RefNr.Text);

        if (FilteredDataRef == null) {
            UIAlertView InvalidAlert = new UIAlertView ("Reference number invalid", "The reference number that you have entered is not linked to the current security code. You can change your security code in the settings.", null, "OK", null);
            InvalidAlert.Show ();

        } else {
            FilteredDataReceived = _FetchingData.FilteringOnReceived (FilteredDataRef);

            FilteredDataPlanned = _FetchingData.FilteringOnPlanned (FilteredDataRef);

            FilteredDataLoadingETA = _FetchingData.FilteringOnLoadingETA (FilteredDataRef);

            FilteredDataLoadingFinal = _FetchingData.FilteringOnLoadingFinal (FilteredDataRef);

            FilteredDataUnloadingETA = _FetchingData.FilteringOnUnloadingETA (FilteredDataRef);

            FilteredDataUnloadingFinal = _FetchingData.FilteringOnUnloadingFinal (FilteredDataRef);   

            this.PerformSegue (MoveToTrackTraceDetailsSegue, this);

            //foreach (string s in FilteredDataPlanned)
            //    Console.WriteLine (s);

        }

    } else {
        UIAlertView InvalidAlert = new UIAlertView ("Reference number cannot be empty", "You did not provide a reference number. We need your reference number to trace identify the shipment you would like to trace.", null, "OK", null);
        InvalidAlert.Show ();
    }
};

下载数据:

public IEnumerable<string> getTrackTraceData (string securityCode, string referenceNumber)
{
    WebRequest request = WebRequest.Create ("http://plex.janssen1877.com/app/life/" + securityCode);

    HttpWebResponse response = (HttpWebResponse)request.GetResponse ();

    Stream dataStream = response.GetResponseStream ();

    StreamReader reader = new StreamReader (dataStream);

    string FetchedData = reader.ReadToEnd ();

    reader.Close ();

    dataStream.Close ();

    response.Close ();

    var FetchingDataItems = FetchedData.Split (new char[] { '\n' });

    if (FetchingDataItems != null) {
        var filteredResult = FetchingDataItems.Where (x => x.Contains (referenceNumber));

        return filteredResult;
    } else {
        return null;
    }
}

现在我想使用名为BTProgressHUD的组件。这只是一个花哨的旋转器。我想如果我将BTProgressHUD.show();放在按钮操作的顶部,BTProgressHUD.Dismiss();放在按钮上,它会在加载开始时显示,并在加载完成时解除。

事实并非如此。它在新视图控制器中显示得非常快,并在一秒钟内再次解除。我做错了什么?

编辑例如:

public IEnumerable<string> getTrackTraceData (string securityCode, string referenceNumber)
        {


            string url = string.Format ("http://plex.janssen1877.com/app/life/" + securityCode);

            HttpWebRequest HttpRequest = (HttpWebRequest)WebRequest.Create (url);

            string FetchedData = new StreamReader (HttpRequest.GetResponse ().GetResponseStream ()).ReadToEnd ();


            var FetchingDataItems = FetchedData.Split (new char[] { '\n' });

            if (FetchingDataItems != null) {
                var filteredResult = FetchingDataItems.Where (x => x.Contains (referenceNumber));

                return filteredResult;
            } else {
                return null;
            }


        }

2 个答案:

答案 0 :(得分:3)

弗洛里安,

根据.NET文档和HttpWebRequest GetResponse. How to wait for that response?,您需要以异步方式执行下载(可能是解析)。

您的实际应用程序的行为是正确的。当您在主线程中执行同步请求时,您冻结了应用程序,因此UI元素不会更新。主线程以串行方式处理执行。

为避免这种情况,您有两种不同的解决方案。一方面,您需要转移到异步请求。另一方面,您可以使用同步请求创建后台线程(不同的执行路径)。我更喜欢前者。因此,例如,在启动异步请求后,显示指示符。完成后(在回调中),关闭指标并执行segue。

例如,您可以按照以下有关如何实现此目的的讨论:How to use HttpWebRequest (.NET) asynchronously?

要了解主线程(和运行循环)的工作原理,我建议您阅读The pogo stick of NSRunLoop

希望有所帮助。

修改

您应该使用类似以下的模式(来源How to use HttpWebRequest (.NET) asynchronously?):

HttpWebRequest webRequest;

void StartWebRequest()
{
    webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}

void FinishWebRequest(IAsyncResult result)
{
    webRequest.EndGetResponse(result);
}

答案 1 :(得分:1)

听起来你正试图在与UI相同的线程中完成所有这些操作,这就是为什么你的应用程序会冻结并等待处理完成而不显示任何内容。我会在某种背景工作中执行此下载操作。然后我不确定Mono,但访问前后主线程并显示和解除你的加载组件。