Closed. This question needs to be more focused。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?更新问题,使其仅通过editing this post专注于一个问题。
                        
                        5年前关闭。
                                                                                            
                
        
我仍在学习Xamarin.iOs,并且为了获得一些概念上的证明,我正在使用Monotouch.Dialog创建员工目录。它在iPhone模拟器上效果很好,但是当我在物理设备上执行它时,会发生3种奇怪的事情:


随机地(有时在模拟器上,但有时在设备上),我有一个超时异常,在异步方法中调用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();
            }
        }
    }
}

我异步加载数据,但是如果使用async / await关键字,则应用程序无法在设备上启动,因为UI线程正在等待加载完成,这花费了太多时间。我改用Task.Factory.StartNew来解决此问题,但我想知道为什么设备和模拟器上的行为不同。
我的最后一个问题是,当我从Web服务收到答案时,我将建立一个添加到本节的Element列表。我有很多元素,但没有那么多(大约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.");
        });
    }
}



这是执行时控制台的结果:


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


异步编程模型可能是我做错了,但是我无法弄清楚到底是什么。

谢谢

最佳答案

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

10-07 13:29