我仍在努力学习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.");
});
}
}
这是执行时控制台的结果:
这可能是我对异步编程模型的错误,但我无法弄清楚到底是什么。
由于
答案 0 :(得分:1)
System.Net.WebException: The operation has timed out at System.Net.HttpWebRequest.GetRequestStream()
。如果查看异常的Response.StatusCode
属性,您肯定会发现它是4xx
http错误。这意味着服务器而不是客户端对此负责。所以修复这个服务器端。AppDelegate.FinishedLaunching
返回时间很短(17秒)。如果超过这个时间,您的应用程序将被终止。启动后台线程是可行的方法。模拟器上的限制可能略有不同,因为众所周知,模拟器中的调试代码比在设备上运行发布代码要慢。MonoTouch.Dialog
的内部结构,但是修复它的一种方法是使用UITableView
,因此只有当单元格的渲染才会发生。必需的。