在下载数据时在MonoTouch中显示旋转器

本文关键字:显示 旋转 MonoTouch 下载 数据 | 更新日期: 2023-09-27 18:09:27

所以在我的应用程序中,我有一个按钮,它与一个从互联网下载一些数据并过滤它的库对话。当应用程序这样做时,屏幕冻结,用户看起来就像应用程序崩溃了。但事实并非如此,因为它正在下载数据。

下面是我的代码:
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;
            }

        }

在下载数据时在MonoTouch中显示旋转器

Florian,

根据。net文档和HttpWebRequest GetResponse。如何等待回应?您需要以异步方式执行下载(可能还有解析)。

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

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

例如,你可以按照下面的讨论来实现这一点:如何异步使用HttpWebRequest (. net) ?

要理解主线程(和运行循环)是如何工作的,我建议阅读关于NSRunLoop的pogo stick。

希望对你有帮助。

编辑

你应该使用如下模式(来源:如何异步使用HttpWebRequest (.NET) ?):

HttpWebRequest webRequest;
void StartWebRequest()
{
    webRequest.BeginGetResponse(new AsyncCallback(FinishWebRequest), null);
}
void FinishWebRequest(IAsyncResult result)
{
    webRequest.EndGetResponse(result);
}

这听起来像你试图做所有这些在同一个线程作为你的UI,这就是为什么你的应用程序冻结,等待处理完成而不显示任何东西。我将在某种类型的后台工作程序中执行此下载操作。然后我不确定在Mono,但访问主线程之前和之后,显示和驳回你的加载组件。