0

私のアプリには、インターネットからデータをダウンロードしてフィルタリングするライブラリと通信するボタンがあります。アプリがこれを行っているとき、画面がフリーズし、ユーザーにはアプリがクラッシュしたように見えます。ただし、データをダウンロードしているため、これは当てはまりません。

これが私のコードです:

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();、ロードが開始されたときに表示され、ロードが完了すると閉じられると思いました。

これはそうではありません。新しいView Controllerに非常にすばやく表示され、1秒以内に再び閉じます. 私は何を間違っていますか?

たとえば編集:

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;
            }


        }
4

2 に答える 2

3

フロリアン、

.NET ドキュメントおよびHttpWebRequest GetResponse によると。その応答を待つ方法は?ダウンロード(およびおそらく解析)を非同期で実行する必要があります。

実際のアプリケーションの動作は正しいです。メイン スレッドで同期要求を実行すると、アプリケーションがフリーズするため、UI 要素が更新されません。メイン スレッドは、シリアル方式で実行を処理します。

これを回避するには、2 つの異なる解決策があります。一方では、非同期リクエストに移行する必要があります。一方、同期要求を使用してバックグラウンド スレッド (別の実行パス) を作成できます。私は前者の方が好きです。したがって、たとえば、非同期リクエストを開始した後、インジケーターを表示します。(コールバックで)終了したら、インジケーターを閉じて、セグエを実行します。

たとえば、これを実現する方法については、次の説明に従ってください: HttpWebRequest (.NET) を非同期的に使用する方法は? .

メインスレッド (および実行ループ) がどのように機能するかを理解するには、NSRunLoop のポゴスティックについて読むことをお勧めします。

それが役立つことを願っています。

編集

次のようなパターンを使用する必要があります (ソースHow to use HttpWebRequest (.NET) asynchronously? ):

HttpWebRequest webRequest;

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

void FinishWebRequest(IAsyncResult result)
{
    webRequest.EndGetResponse(result);
}
于 2013-04-16T20:59:51.540 に答える
1

これらすべてを UI と同じスレッドで実行しようとしているようです。そのため、アプリはフリーズし、何も表示せずに処理が完了するのを待ちます。このダウンロード操作は、何らかのバックグラウンド ワーカーで実行します。次に、モノではわかりませんが、前後にメインスレッドにアクセスし、読み込み中のコンポーネントを表示して閉じます。

于 2013-04-16T21:06:55.797 に答える