0

私はまだ Xamarin.iOs の学習に取り組んでおり、概念を少し証明するために、Monotouch.Dialog を使用して従業員ディレクトリを作成しています。iPhone シミュレーターでは問題なく動作しますが、物理デバイスで実行すると、3 つの奇妙なことが起こります。

  1. ランダムに(シミュレーターで時々、デバイスでより頻繁に)、非同期メソッドで HttpWebRequest.GetRequestStream() を呼び出すタイムアウト例外が発生しました。ただし、メソッドが呼び出されるたびに新しい HttpWebRequest を作成し、すべてを適切に閉じて破棄すると思います。コードのスニペットは次のとおりです。

    var wr = HttpWebRequest.Create(url);
    byte[] streamContent = System.Text.Encoding.UTF8.GetBytes(body);
    Stream dataStream = wr.GetRequestStream(); //timeout on that statement !
    dataStream.Write(streamContent, 0, streamContent.Length);
    dataStream.Close();
    using (var response = (await wr.GetResponseAsync().ConfigureAwait(false)))
    {
        if (response != null)
        {
            try
            {
                var webResponse = response as HttpWebResponse;
                if (webResponse != null && webResponse.StatusCode == HttpStatusCode.OK)
                {
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream()))
                    {
                        var responseText = reader.ReadToEnd();
                        result = JsonConvert.DeserializeObject<T>(responseText);
                        reader.Close();
                    }
                }
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
        }
    }
    
  2. データを非同期で読み込みますが、async / await キーワードを使用すると、UI スレッドが読み込みの完了を待機しているように見え、時間がかかりすぎるため、アプリケーションをデバイスで起動できませんでした。代わりに Task.Factory.StartNew を使用してこの問題を修正しましたが、デバイスとシミュレータで動作が異なるのはなぜだろうと思っていました。

  3. 最後の問題は、Web サービスから回答を受け取ったときに、セクションに追加する要素のリストを作成することです。私は多くの要素を持っていますが、それほど多くはありません (約 700)。シミュレーターで画面を更新するのに約 2 秒かかりますが、デバイス (第 4 世代の iPod touch) では 1 分以上かかります。要素を作成して画面を更新するために使用するコードがあります (非同期で実行されるため、 InvokeOnMainThread() を使用します) :

    private void updateEmployeeList(IEnumerable<EmployeSummary> list, Section section)
    {
        if (list != null && list.Any())
        {
            var q = list.Select(item =>
            {
                StyledStringElement newCell = new StyledStringElement(item.FullName) { Accessory = UITableViewCellAccessory.DisclosureIndicator };
                newCell.Tapped +=
                () => _detailScreenVM.ShowDetail(item);
                return newCell;
            }).ToList();
            _logger.Log("Items to add : {0}", q.Count);
            InvokeOnMainThread(() =>
            {
                _logger.Log("Starting updating screen");
                section.AddAll(q);
                _logger.Log("Ending updating screen.");
            });
        }
    }
    

実行時のコンソールの結果は次のとおりです。

  • 追加する項目: 690 at 15:29:57.896041
  • 15:29:57.903079 に画面更新を開始
  • 15:31:03.548430 更新画面終了

それはおそらく非同期プログラミングモデルで私が間違っていることですが、正確にはわかりません。

ありがとう

4

1 に答える 1

1
  1. タイムアウトはSystem.Net.WebException: The operation has timed out at System.Net.HttpWebRequest.GetRequestStream(). 例外のプロパティを見ると、確かにhttp エラーResponse.StatusCodeであることがわかります。4xxこれは、クライアントではなくサーバーがこれを担当することを意味します。そこで、このサーバー側を修正します。
  2. AppDelegate.FinishedLaunching戻るまでの時間はほとんどありません (17 秒) 。この時間を超えると、アプリは強制終了されます。バックグラウンド スレッドを開始する方法です。シミュレーターでのデバッグ コードは、デバイスでのリリース コードの実行よりも遅いことがよく知られているため、シミュレーターでは制限が若干異なる場合があります。
  3. ここで何が問題なのかはわかりませんし、 の内部もわかりませんが、MonoTouch.Dialogそれを修正する方法は を使用するUITableViewことで、セルのレンダリングは必要な場合にのみ行われます。
于 2013-09-30T07:57:48.067 に答える