Monotouch.Dialog需要很长时间才能刷新屏幕

时间:2013-09-27 20:35:33

标签: c# ios xamarin.ios xamarin

我仍在努力学习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. 我的最后一个问题是,当我从我的网络服务收到答案时,我会构建一个我添加到我的部分的元素列表。我有很多元素但不是那么多(约700)。在模拟器中刷新屏幕需要大约2秒钟,但在设备上超过1分钟(第四代ipod touch)。我使用的代码来创建我的元素并刷新屏幕(它运行异步,这就是我使用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.");
            });
        }
    }
    
  4. 这是执行时控制台的结果:

    • 要添加的项目:690 at 15:29:57.896041
    • 在15:29:57.903079开始更新屏幕
    • 结束更新屏幕时间为15:31:03.548430

    这可能是我对异步编程模型的错误,但我无法弄清楚到底是什么。

    由于

1 个答案:

答案 0 :(得分:1)

  1. 我猜超时是System.Net.WebException: The operation has timed out at System.Net.HttpWebRequest.GetRequestStream()。如果查看异常的Response.StatusCode属性,您肯定会发现它是4xx http错误。这意味着服务器而不是客户端对此负责。所以修复这个服务器端。
  2. 您的AppDelegate.FinishedLaunching返回时间很短(17秒)。如果超过这个时间,您的应用程序将被终止。启动后台线程是可行的方法。模拟器上的限制可能略有不同,因为众所周知,模拟器中的调试代码比在设备上运行发布代码要慢。
  3. 我不知道这里有什么问题,也不知道MonoTouch.Dialog的内部结构,但是修复它的一种方法是使用UITableView,因此只有当单元格的渲染才会发生。必需的。