我仍在努力学习 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 解决了这个问题,但我想知道为什么设备和模拟器上的行为不同。
我的最后一个问题是,当我从我的网络服务收到答案时,我构建了一个添加到我的部分的元素列表。我有很多元素,但没有那么多(大约 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 结束更新屏幕
这可能是我对异步编程模型做错了,但我无法弄清楚到底是什么。
谢谢