<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_张志敏</title><subtitle type="text">目前聚焦于以下领域： MonoTouch， WPF/Silverlight， ASP.NET MVC, WCF REST, NHibernate </subtitle><id>http://feed.cnblogs.com/blog/u/12542/rss</id><updated>2012-01-16T01:37:32Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/12542/rss"/><entry><id>http://www.cnblogs.com/beginor/archive/2012/01/16/2323265.html</id><title type="text">使用 Task 简化异步编程</title><summary type="text">本文介绍了常见的 .Net 异步编程模式， 以及如何用 Task 对象包装这些异步编程模式， 并给出了一个使用 Task 对象包装异步操作， 简化代码的例子。</summary><published>2012-01-16T01:36:00Z</published><updated>2012-01-16T01:36:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/01/16/2323265.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/01/16/2323265.html"/><content type="html">&lt;p&gt;&lt;strong&gt;.Net 传统异步编程概述&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;.NET Framework 提供以下两种执行 I/O 绑定和计算绑定异步操作的标准模式：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;异步编程模型 (APM)，在该模型中异步操作由一对 Begin/End 方法（如 FileStream.BeginRead 和 Stream.EndRead）表示。 &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;基于事件的异步模式 (EAP)，在该模式中异步操作由名为“操作名称Async”和“操作名称Completed”的方法/事件对（例如 WebClient.DownloadStringAsync 和 WebClient.DownloadStringCompleted）表示。 （EAP 是在 .NET Framework 2.0 版中引入的）。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;Task 的优点以及功能&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;通过使用 Task 对象，可以简化代码并利用以下有用的功能：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;在任务启动后，可以随时以任务延续的形式注册回调。 &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;通过使用 ContinueWhenAll 和 ContinueWhenAny 方法或者 WaitAll 方法或 WaitAny 方法，协调多个为了响应 Begin_ 方法而执行的操作。 &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;在同一 Task 对象中封装异步 I/O 绑定和计算绑定操作。 &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;监视 Task 对象的状态。 &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;使用 TaskCompletionSource&lt;TResult&gt; 将操作的状态封送到 Task 对象。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;使用 Task 封装常见的异步编程模式&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;1、 使用 Task 对象封装 APM 异步模式， 这种异步模式是 .Net 标准的异步模式之一， 也是 .Net 最古老的异步模式，  自 .Net 1.0 起就开始出现了，通常由一对 Begin/End 方法同时出现， 以 WebRequest 的 BeginGetResponse 与 EndGetResponse 方法为例：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;var request = WebRequest.CreateHttp(UrlToTest);&#xD;
request.Method = "GET";&#xD;
var requestTask = Task.Factory.FromAsync&amp;lt;WebResponse&gt;(&#xD;
   request.BeginGetResponse,&#xD;
   request.EndGetResponse,&#xD;
   null&#xD;
);&#xD;
requestTask.Wait();&#xD;
var response = requestTask.Result;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;2、使用 Task 对象封装 EPM 异步模式， 这种模式从 .Net 2.0 开始出现， 同时在 Silverlight 中大量出现， 这种异步模式以 “操作名称Async” 函数和 “操作名称Completed” 事件成对出现为特征， 以 WebClient 的 DownloadStringAsync 方法与 DownLoadStringCompleted 事件为例：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;var source = new TaskCompletionSource&amp;lt;string&gt;();&#xD;
var webClient = new WebClient();&#xD;
webClient.DownloadStringCompleted += (sender, args) =&gt; {&#xD;
   if (args.Cancelled) {&#xD;
      source.SetCanceled();&#xD;
      return;&#xD;
   }&#xD;
   if (args.Error != null) {&#xD;
      source.SetException(args.Error);&#xD;
      return;&#xD;
   }&#xD;
   source.SetResult(args.Result);&#xD;
};&#xD;
webClient.DownloadStringAsync(new Uri(UrlToTest, UriKind.Absolute), null);&#xD;
source.Task.Wait();&#xD;
var result = source.Task.Result;&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;3、 使用 Task 对象封装其它非标准异步模式， 这种模式大量出现在第三方类库中， 通常通过一个 Action 参数进行回调， 以下面的方法为例：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;void AddAsync(int a, int b, Action&amp;lt;int&gt; callback)&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;封装方法与封装 EPM 异步模式类似：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;var source = new TaskCompletionSource&amp;lt;int&gt;();&#xD;
Action&amp;lt;int&gt; callback = i =&gt; source.SetResult(i);&#xD;
AddAsync(1, 2, callback);&#xD;
source.Task.Wait();&#xD;
var result = source.Task.Result;&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;通过上面的例子可以看出， 用 Task 对象对异步操作进行封装之后， 异步操作简化了很多， 只要调用 Task 的 Wait 方法， 可以直接获取异步操作的结果， 而不用转到回调函数中进行处理， 接下来看一个比较实际的例子。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;缓冲查询示例&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;以 Esri 提供的缓冲查询为例， 用户现在地图上选择一个合适的点， 按照一定半径查询查询缓冲区， 再查询这个缓冲区内相关的建筑物信息， 这个例子中， 我们需要与服务端进行两次交互：&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;ol&gt;&#xD;
	&lt;li&gt;根据用户选择的点查询出缓冲区；&lt;/li&gt;&#xD;
	&lt;li&gt;查询缓冲区内的建筑物信息；&lt;/li&gt;&#xD;
&lt;/ol&gt;&#xD;
&#xD;
&lt;p&gt;这个例子在 GIS 查询中可以说是非常简单的， 也是很典型的， &lt;a href="http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#BufferQuery" target="_blank"&gt;ESRI 的例子中也给出了完整的源代码&lt;/a&gt;， 这个例子的核心逻辑代码是：&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;_geometryService = new GeometryService(GeoServerUrl);&#xD;
_geometryService.BufferCompleted += GeometryService_BufferCompleted;&#xD;
&#xD;
_queryTask = new QueryTask(QueryTaskUrl);&#xD;
_queryTask.ExecuteCompleted += QueryTask_ExecuteCompleted;&#xD;
&#xD;
void MyMap_MouseClick(object sender, Map.MouseEventArgs e) {&#xD;
   // 部分代码省略， 开始缓冲查询&#xD;
   _geometryService.BufferAsync(bufferParams);&#xD;
&#xD;
}&#xD;
&#xD;
void GeometryService_BufferCompleted(object sender, GraphicsEventArgs args) {&#xD;
   // 部分代码省略， 获取缓冲查询结果， 开始查询缓冲区内的建筑物信息&#xD;
   _queryTask.ExecuteAsync(query);&#xD;
}&#xD;
&#xD;
void QueryTask_ExecuteCompleted(object sender, QueryEventArgs args) {&#xD;
   // 将查询结果更新到界面上&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;这只是一个 GIS 开发中很简单的一个查询， 上面的代码却将逻辑分散在三个函数中， 在实际应用中， 与服务端的交互次数会更多， 代码的逻辑会分散在更多的函数中， 导致代码的可读性以及可维护性降低。 如果使用 Task 对象对这些任务进行封装， 那么整个逻辑将会简洁很多， GeometryService 和 QueryTask 提供的是 EPM 异步模式， 相应的封装方法如上所示， 最后， 用 Task 封装异步操作之后的代码如下：&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;void MyMap_MouseClick(object sender, Map.MouseEventArgs e) {&#xD;
   Task.Factory.StartNew(() =&gt; {&#xD;
      // 省略部分 UI 代码， 开始缓冲查询&#xD;
      var bufferParams = new BufferParameters() { /* 初始化缓冲查询参数 */};&#xD;
      var bufferTask = _geometryService.CreateBufferTask()&#xD;
      // 等待缓冲查询结果&#xD;
      bufferTask.Wait();&#xD;
      // 省略更新 UI 的代码， 开始查询缓冲区内的建筑物信息&#xD;
      var query = new Query() { /* 初始化查询参数 */ };&#xD;
      var queryExecTask = _queryTask.CreateExecTask(query);&#xD;
      queryExecTask.Wait();&#xD;
      // 将查询结果显示在界面上， 代码省略&#xD;
   });&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;从上面的代码可以看出， 使用 Task 对象可以把原本分散在三个函数中的逻辑集中在一个函数中即可完成， 代码的可读性、可维护性比原来增加了很多。&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Task 能完成的任务远不止这些，比如并行计算、 协调多个并发任务等， 有兴趣的可以进一步阅读&lt;a href="http://msdn.microsoft.com/zh-cn/library/dd997405.aspx" target="_blank"&gt;相关的 MSDN 资料&lt;/a&gt;。 &lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2323265.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/01/16/2323265.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2012/01/06/2314331.html</id><title type="text">ROW_NUMBER 函数</title><summary type="text">SQL 2005 ROW_NUMBER 函数简介</summary><published>2012-01-06T05:31:00Z</published><updated>2012-01-06T05:31:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2012/01/06/2314331.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2012/01/06/2314331.html"/><content type="html">&lt;p&gt;ROW_NUMBER 是 SQL 2005 中新增的函数， 多用于分页， 基本的语法为&lt;/p&gt;  &lt;pre &gt;ROW_NUMBER() OVER([&amp;lt;partition_by_clause&gt;] &amp;lt;order_by_clause&gt;)&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;其中， 分区语句是可选的， 排序语句是必须的， 比如这样的语句：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;SELECT&#xD;
  ROW_NUMBER() OVER(ORDER BY ProductID),&#xD;
  CategoryID,&#xD;
  ProductName,&#xD;
  UnitPrice&#xD;
FROM&#xD;
  Products&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;输出结果为：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/beginor/201201/201201061327394093.png" width="492" height="342" /&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;也可以按照 CategoryID 对行号进行分区， 也就是将行号按照 CategoryID 进行分组， 例如：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;SELECT&#xD;
  ROW_NUMBER() OVER(PARTITION BY CategoryID ORDER BY ProductID),&#xD;
  CategoryID,&#xD;
  ProductName,&#xD;
  UnitPrice&#xD;
FROM&#xD;
  Products&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;返回结果为：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/beginor/201201/201201061327409533.png" width="488" height="346" /&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;ROW_NUMBER 通常用于分页， 但是也有一些巧妙地用法， 例如， 要查询每个分类中最便宜的三种产品， 可以使用下面的查询语句：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;SELECT * FROM&#xD;
(&#xD;
  SELECT&#xD;
    ROW_NUMBER() OVER(PARTITION BY CategoryID ORDER BY UnitPrice) AS 'RowNum',&#xD;
    CategoryID,&#xD;
    ProductName,&#xD;
    UnitPrice&#xD;
  FROM&#xD;
    Products&#xD;
) AS p&#xD;
WHERE&#xD;
  RowNum &amp;lt;= 3&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;返回结果为：&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/beginor/201201/201201061327401976.png" width="473" height="343" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2314331.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2012/01/06/2314331.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/12/28/2304215.html</id><title type="text">升级 ExtJS 至 4.0.7 时遇到的几个小问题</title><summary type="text">升级 ExtJS 至 4.0.7 时遇到的几个小问题以及对应的解决方法。</summary><published>2011-12-27T23:28:00Z</published><updated>2011-12-27T23:28:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/12/28/2304215.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/12/28/2304215.html"/><content type="html">&lt;p&gt;&lt;b&gt;1、 新的类库体系&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
旧的类定义方式为：&lt;br /&gt;&#xD;
&lt;pre &gt;App.view.Viewport = Ext.extend(Ext.panel.Panel, {&#xD;
   initComponent: function() {&#xD;
      // call parent initComponent method&#xD;
      App.view.Viewport.superclass.initComponent.apply(this, arguments);&#xD;
   }&#xD;
});&#xD;
&lt;/pre&gt;&#xD;
新的类定义方式为：&lt;br /&gt;&#xD;
&lt;pre &gt;Ext.define('App.view.Viewport', {&#xD;
   initComponent: function() {&#xD;
      // call parent &#xD;
      this.callParent(arguments);&#xD;
   }&#xD;
});&#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;b&gt;2、 Ext.Loader 动态加载 js 文件&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
4.0.7 版本的 Ext.Loader  默认是未启用动态加载的， 导致运行时会报错， 要手工设置启用动态加载， 启用动态加载的代码为：&lt;br /&gt;&#xD;
&lt;pre &gt;Ext.Loader.setConfig({  enabled: true });&#xD;
&lt;/pre&gt;&#xD;
Ext.Loader 还有几个有用的参数（paths、 disableCaching）等，  可以查看相关 Ext.Loader API。&#xD;
&#xD;
&lt;p&gt;&lt;b&gt;3、 Ext.panel.Panel 的 onResize 方法已经删除&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
没错， Ext.panel.Panel 的 onResize 方法已经删除， 重写 onResize 方法的类需要稍微修改一下， 推荐使用 componentLayout 事件或者 afterComponentLayout 方法。&#xD;
&#xD;
&lt;p&gt;&lt;b&gt;4、 Ext.panel.Panel 的 collapsible 设置为 true 时，必须设置 panel 宽度&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
 如果没有设置 panel 的宽度， 点击 panel 的 collapse 工具按钮时， 会导致整个 panel 不可见。&#xD;
&#xD;
&lt;p&gt;&lt;b&gt;5、 不能手工刷新 Ext.form.ComboBox 的 store 的数据&lt;/b&gt;&lt;/p&gt;&#xD;
&#xD;
如果用代码刷新了 ComboBox 的 store 的数据， 会导致其弹出的选择列表一直显示“正在加载”， 无法进行选择， 如果必须要刷新 store 数据， 只能改用其它的控件代替 ComboBox。&#xD;
&lt;img src="http://www.cnblogs.com/beginor/aggbug/2304215.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/12/28/2304215.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/12/11/2284055.html</id><title type="text">Razor 视图引擎学习</title><summary type="text">Asp.Net Mvc 3 Razor 视图引擎学习</summary><published>2011-12-11T09:33:00Z</published><updated>2011-12-11T09:33:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/12/11/2284055.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/12/11/2284055.html"/><content type="html">&lt;p&gt;Razor 视图文件扩展名为 cshtml 或者 vbhtml ， 现在主要讨论 cshtml。&#xD;
&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@ 定义 Razor 语句&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;&lt;p&gt;&lt;strong&gt; Name: @Model.Name &lt;/strong&gt;&lt;/p&gt;&#xD;
Time View Rendered: @Date.Time.ToShoarTimeString()&#xD;
@if (Model.Category == "Watersports") {&#xD;
   &lt;p&gt;@Model.Category &lt;b&gt;Splash!&lt;/b&gt; &lt;/p&gt;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@: 输出单行不是以 html 标记开头的， 并且要包含 html 标记的内容&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;@if (Model.Category == "Watersports") {&#xD;
   @: Category: @Model.Category &lt;b&gt;Splash!&lt;/b&gt;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;&amp;lt;text&gt;&amp;lt;/text&gt; 输出多行包含 html 标记的内容&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;@if (Model.Category == "Watersports") {&#xD;
   &lt;text&gt;&#xD;
   @: Category: @Model.Category &lt;b&gt;Splash!&lt;/b&gt;&#xD;
   &lt;pre&gt;Row, row, row your boat,&#xD;
      Gently down the stream ...&#xD;
   &lt;/pre&gt;&#xD;
   &lt;/text&gt;&#xD;
} &#xD;
&lt;/pre&gt;&#xD;
&lt;p&gt;&lt;strong&gt;@model  表示使用模型对象的类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
@model Razor.Models.Product&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@{} 表示代码段&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;pre &gt;@{&#xD;
   if (Model.Category == "Watersports") {&#xD;
      @: Category: @Model.Category &lt;b&gt;Splash!&lt;/b&gt;&#xD;
   }&#xD;
   if (Model.Price &gt; 10) {&#xD;
      &lt;p&gt;&lt;strong&gt;Pricey!&lt;/strong&gt;&lt;/p&gt;&#xD;
   }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;使用布局页面&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
在 cshtml 文件的开头可以指定使用哪个布局页面， 例如：&#xD;
&lt;pre &gt;@{&#xD;
   Layout = "~/Views/Shared/_Layout.cshtml";&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
如果不指定 Layout 属性， Razor 引擎会检查 Views 目录下面的 _ViewStart.cshtml 文件， 这个页面指定了默认的布局页面。&#xD;
&#xD;
如果不是用布局页面， 则需要在页面的开头添加声明如下：&#xD;
&#xD;
@{&#xD;
   Layout = null;&#xD;
}&#xD;
&#xD;
以下划线 (_) 开头的视图文件不会返回给用户， 只能在服务端 cshtml 文件中进行引用。&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@RenderBody() 渲染子视图&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
表示在此渲染子视图， 只能出现在布局页面中， 且只能出现一次。&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@RenderPage 渲染另一个页面&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
表示在当前位置渲染另外一个页面。&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@RenderSection(name, required) 渲染一个区域&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
表示在当前页面渲染一个区域， 区域名称在布局页面定义， required 表示该区域是否为可选的。&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;@region name {} 实现一个区域的内容&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
与布局页面的 @RenderSection 相对应， 实现布局页面的定义的区域。&#xD;
&lt;img src="http://www.cnblogs.com/beginor/aggbug/2284055.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/12/11/2284055.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/10/31/2229783.html</id><title type="text">NHibernate 使用流畅 API 进行配置</title><summary type="text">NHibernate 使用流畅 API 进行配置的示例代码</summary><published>2011-10-31T01:35:00Z</published><updated>2011-10-31T01:35:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/10/31/2229783.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/10/31/2229783.html"/><content type="html">&lt;p&gt;&lt;strong&gt;1、 创建一个 Configuration &lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;using Nhibernate.cfg;&#xD;
&#xD;
var config = new Configuration()&#xD;
.SetProperty("connection.provider", "NHibernate.Connection.DriverConnectionProvider")&#xD;
.SetProperty("connection.driver_class", "NHibernate.Driver.SqlClientDriver")&#xD;
.SetProperty("dialect", "NHibernate.Dialect.MsSql2005Dialect")&#xD;
.SetProperty("proxyfactory.factory_class", "NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate")&#xD;
.SetProperty("format_sql", "true")&#xD;
.SetProperty("show_sql", "true")&#xD;
.SetProperty("connection.connection_string", connectionString);&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2、 添加映射&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;using NHibernate.Mapping.ByCode;&#xD;
&#xD;
var mapper = new ModelMapper();&#xD;
mapper.Class&lt;Category&gt;(cm =&gt; {&#xD;
   cm.Schema("dbo");&#xD;
   cm.Table("Categories");&#xD;
   cm.Id(cat =&gt; cat.CategoryID, map =&gt; {&#xD;
      map.Column("CategoryID");&#xD;
      map.Generator(Generators.Native);&#xD;
   });&#xD;
   cm.Property(cat =&gt; cat.CategoryName, map =&gt; {&#xD;
      map.Column("CategoryName");&#xD;
      map.Length(100);&#xD;
   });&#xD;
   cm.Property(cat =&gt; cat.Description, map =&gt; {&#xD;
      map.Column("Description");&#xD;
      map.Length(200);&#xD;
   });&#xD;
});&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;3、 添加映射至 Configuration &lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;pre  &gt;var mappingDocument = mapper.CompileMappingForAllExplicitlyAddedEntities();&#xD;
config.AddMapping(mappingDocument);&#xD;
&lt;/pre&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2229783.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/10/31/2229783.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/10/18/2216766.html</id><title type="text">MonoTouch 中的线程</title><summary type="text">介绍 MonoTouch 线程的使用 。</summary><published>2011-10-18T10:01:00Z</published><updated>2011-10-18T10:01:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/10/18/2216766.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/10/18/2216766.html"/><content type="html">&lt;p&gt;在 MonoTouch 中， 可以使用标准的 .Net 线程 API ， 既可以直接使用线程（System.Threading.Thread、System.Threading.ThreadPool）， 也可以简介使用异步委托模式以及 BeginXXX 、 EndXXX 方法。&lt;/p&gt;  &lt;p&gt;最好使用 Mono 的线程池， 这样，系统的开销增加的非常缓慢， 充分利用多核来平衡系统的负载以及程序的需求。 可以通过调用 System.Threading.ThreadPool 的方法或者使用默认的 System.Threading.Tasks.TaskScheduler (Parallel Framework 的一部分) 来使用线程池。&lt;/p&gt;  &lt;p&gt;通常， 当开发者需要创建即时响应界面并且不希望阻塞主界面的程序时， 需要用到线程。&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;开发即时响应的应用&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;对界面元素的操作必须限制在运行主界面循环的线程， 如果需要线程中对界面做修改， 则必须使用 &lt;a href="http://api.xamarin.com/index.aspx?link=T%3AMonoTouch.Foundation.NSObject%2FM" target="_blank"&gt;NSObject.InvokeOnMainThread&lt;/a&gt; 把代码添加到队列， 例如：&lt;/p&gt;  &lt;pre &gt;MyThreadedRoutine() {&#xD;
   var result = DoComputation();&#xD;
   // 计算完成之后， 需要更新界面， 需要保证操作界面的代码一定是在主界面线程执行&#xD;
   InvokeOnMainThread(delegate {&#xD;
      label.Text = &amp;quot;The result is: &amp;quot; + result;&#xD;
   });&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;上面的委托中的代码会在主界面线程的上下文中执行， 没有任何竞争条件， 不会导致程序崩溃。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;线程与垃圾回收&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Objective-C 运行时会在执行的过程中创建和销毁对象， 如果对象被标记为 “auto-release” ， Objective-C 运行时将会把这些对象放到线程当前的 NSAutoReleasePool 进行销毁。 MonoTouch 为主界面线程以及每个由 ThreadPool 创建的线程分配一个 NSAutoReleasePool， 当然也包括用默认 TaskScheduler 创建的 Task 。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;如果需要创建自己的线程， 则必须也提供一个 NSAutoReleasePool 来防止内存泄漏， 如果要这样做的话， 用下面的代码包含你的代码即可：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;void MyThreadStart(object arg) {&#xD;
   using (var ns = new NSAutoReleasePool()) {&#xD;
      // Your code goes here.&#xD;
   }&#xD;
}&lt;/pre&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2216766.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/10/18/2216766.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/09/25/2190545.html</id><title type="text">在 MonoTouch 中使用 Newtonsoft.Json</title><summary type="text">本文介绍如何在 MonoTouch 下编译 Newtonsoft.Json 。</summary><published>2011-09-25T14:39:00Z</published><updated>2011-09-25T14:39:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/09/25/2190545.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/09/25/2190545.html"/><content type="html">&lt;p&gt;一直在项目中使用 &lt;a href="http://json.codeplex.com/" target="_blank"&gt;Newtonsoft.Json&lt;/a&gt; 作为服务端的 Json 数据序列化工具， 现在使用 MonoTouch 做 iOS 开发， 自然会选择用 Newtonsoft.Json 来反序列化服务端返回的 Json 数据。&lt;/p&gt;  &lt;p&gt;Newtonsoft.Json 没有提供对 MonoTouch 的版本， 因此需要从源代码编译 NJson 。&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;从 &lt;a href="http://json.codeplex.com/" target="_blank"&gt;NJson 的 CodePlex 主页&lt;/a&gt;下载最新版本的源代码。 &lt;/li&gt;    &lt;li&gt;在源代码的 Src\NewtonSoft.Json 目录下， 有这样的几个项目文件：      &lt;ul&gt;       &lt;li&gt;Newtonsoft.Json.Net20.csproj 对应 .Net 2.0 平台下的 NJson ； &lt;/li&gt;        &lt;li&gt;Newtonsoft.Json.Net35.csproj 对应 .Net 3.5 平台下的 NJson ； &lt;/li&gt;        &lt;li&gt;Newtonsoft.Json.Silverlight.csproj 对应 Silverlight 平台下的 NJson ； &lt;/li&gt;        &lt;li&gt;Newtonsoft.Json.csproj 对应 .Net 4.0 平台下的 NJson ； &lt;/li&gt;        &lt;li&gt;Newtonsoft.Json.WindowsPhone.csproj 对应 WP7 平台下的 NJson； &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;在 Mac 系统下， 用 MonoDevelop 新建一个 MonoTouch 类库项目， 项目名称为 Newtonsoft.Json.MonoTouch， 然后关闭 MonoTouch ； &lt;/li&gt;    &lt;li&gt;用文本编辑器打开 Newtonsoft.Json.MonoTouch.csproj 和 Newtonsoft.Json.Net35.csproj 两个文件， 将 Newtonsoft.Json.Net35.csproj 文件中所有的 &amp;lt;Compile Include=&amp;quot;*.cs&amp;quot; /&amp;gt; 复制到 Newtonsoft.Json.MonoTouch.csproj&amp;#160; 文件中对应的位置， 然后保存 Newtonsoft.Json.MonoTouch.csproj 文件。 &lt;/li&gt;    &lt;li&gt;再用 MonoDevelop 打开 Newtonsoft.Json.MonoTouch.csproj 项目， 打开项目属性对话框， 添加两个编译选项 WINDOWS_PHONE 和 SILVERLIGHT ，&amp;#160; 并将项目的输出文件改为 Newtonsoft.Json.MonoTouch ； &lt;/li&gt;    &lt;li&gt;在项目中添加下列类型的定义文件， 因为这些 Newtonsoft.Json 引用到这些类型， 但是 MonoTouch 下没有这些类型：      &lt;ul&gt;       &lt;li&gt;System.ComponentModel.AddingNewEventHandler &lt;/li&gt;        &lt;li&gt;System.ComponentModel.AddingNewEventArgs &lt;/li&gt;        &lt;li&gt;System.ComponentModel.PropertyChangingEventHandler &lt;/li&gt;        &lt;li&gt;System.ComponentModel.INotifyPropertyChanging &lt;/li&gt;        &lt;li&gt;System.ComponentModel.PropertyChangingEventArgs &lt;/li&gt;     &lt;/ul&gt; 这些类型通过查阅 MSDN 或者用 ILSpy 很容易确定它们是怎么定义的；&lt;/li&gt;    &lt;li&gt;如果不出什么意外的话， 现在可以在 MonoTouch 下编译出 Newtonsoft.Json 了。&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;经过测试， 这样编译出的 NJson 在 MonoTouch 保留了NJon 绝大部分功能， 可以正常的反序列化服务端的 JSON 数据。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2190545.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/09/25/2190545.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/09/24/2189767.html</id><title type="text">MonoTouch 的限制</title><summary type="text">做 MonoTouch 开发已经有一段时间了， 给我的感觉是 MonoTouch 虽然比较可靠， 但是还是有很多限制， 于是翻译了官方文档的的这一篇 MonoTouch 的限制， 以作备忘。</summary><published>2011-09-24T15:07:00Z</published><updated>2011-09-24T15:07:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/09/24/2189767.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/09/24/2189767.html"/><content type="html">&lt;p&gt;做 MonoTouch 开发已经有一段时间了， 给我的感觉是 MonoTouch 虽然比较可靠， 但是还是有很多限制， 于是翻译了官方文档的的&lt;a href="http://ios.xamarin.com/Documentation/Limitations" target="_blank"&gt;这一篇 MonoTouch 的限制&lt;/a&gt;， 以作备忘。&lt;/p&gt;  &lt;p&gt;因为在 iPhone 上运行的 MonoTouch 程序是编译成静态代码的， 所以需要在运行时动态生成代码的功能是不可用的。&lt;/p&gt;  &lt;p&gt;以下是与桌面版的 Mono 相比， MonoTouch 的限制：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. 受限的泛型支持&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;与传统的 Mono/.Net 不同， 在 iPhone 上运行的代码不是由 JIT 编译器动态编译的， 而是是预编译成静态代码的。 Mono 的 &lt;a href="http://www.mono-project.com/AOT#Full_AOT" target="_blank"&gt;Full AOT&lt;/a&gt; 技术在泛型方面有一些限制， 它们是：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1.1 泛型虚函数&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;不支持泛型虚函数， 因为不能静态确定在不同情况下什么方法会被调用。 （这也是 C++ 不支持虚模板函数（virtual template method）的原因）&lt;/p&gt;  &lt;pre &gt;class HasGenericVirtualMethod {&#xD;
   public virtual void PrintValues&lt;t&gt;(params T[] values) { }&#xD;
}&#xD;
&#xD;
var a = new HasGenericVirtualMethod();&#xD;
a.PrintValues(new[] {1,2,3,4});&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1.2 泛型类型中的平台调用&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;不支持在泛型类型中使用平台调用 (P/Invoke)：&lt;/p&gt;&#xD;
&#xD;
&lt;pre &gt;class GenericType&lt;t&gt; {&#xD;
   [DllImport(&amp;quot;System&amp;quot;)]&#xD;
   public static extern int GetPid();&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1.3 不支持在 Nullable 类型上使用 Property.SetInfo&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;不支持在 Nullable&amp;lt;T&amp;gt; 类型上使用反射 Property.SetInfo 设置属性的值。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;1.4 字典的关键字为值类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;将值类型作为 Dictionary&amp;lt;TKey, TValue&amp;gt; 的 Key 是有问题的， 因为 Dictionary 的默认构造函数将会试图使用 EqualityComparer&amp;lt;TKey&amp;gt;.Default 。 EqualityComparer&amp;lt;TKey&amp;gt;.Default 反过来会通过反射去实例化一个新的实现 IEqualityComparer&amp;lt;TKey&amp;gt; 借口的类型。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;对于引用类型来说，这没有什么问题（因为反射+创建新类型的步骤会被跳过）， 但是对于值类型来说， 一旦在移动设备商运行， 你的应用将可能会崩溃。 （原文是：This works for reference types (as the reflection+create a new type step is skipped), but for value types it crashes and burns rather quickly once you attempt to use it on the device.）&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;解决方案： 手工创建一个类型来实现 &lt;a href="http://www.go-mono.com/docs/index.aspx?link=T%3aSystem.Collections.Generic.IEqualityComparer%601" target="_blank"&gt;IEqualityComparer&amp;lt;TKey&amp;gt;&lt;/a&gt; 接口， 并提供一个实例传递给字典的构造函数 &lt;a href="http://www.go-mono.com/docs/monodoc.ashx?link=C%3aSystem.Collections.Generic.Dictionary%602%28System.Collections.Generic.IEqualityComparer%7b%600%7d%29" target="_blank"&gt;Dictionary&amp;lt;TKey, TValue&amp;gt;(IEqualitycomparer&amp;lt;TKey&amp;gt;)&lt;/a&gt; 。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2. 没有动态代码生成&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;由于 iPhone 的内核禁止应用程序动态生成代码， 在 iPhone 上 Mono 不支持任何形式的动态代码生成， 包括：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;System.Reflection.Emit 不可用； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;不支持 System.Runtime.Remoting； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;不支持创建动态类型（例如 Type.GetType(“MyType`1)）， 不过可以创建已知类型（例如： Type.GetType(“System.String”) 可以正常使用）； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;反向回调函数 (Reverse callback) 必须在编译时注册。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2.1 System.Reflection.Emit&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;缺少 System.Reflection.Emit 意味着任何依赖运行时的生成代码的代码不能工作， 它们包括：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;动态语言运行时 (Dynamic Language Runtime)； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;构建于动态语言运行时的任何语言； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;远程调用中的透明代理或者其它任何需要在运行时动态生成代码的东西。 &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;注意： 不要混淆 Reflection.Emit 和 Reflection 。 Reflection.Emit 是关于动态代码生成、对它们进行动态编译，并编译成本地代码。 由于 iPhone 的限制（没有 JIT 编译）， 无法支持这些操作。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;但是关于反射的API， 包括 Type.GetType(“SomeClass”)、 列举类型方法、属性， 获取特性（Attributes）和值是可以使用的。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;2.2 反向回调&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;在标准的 Mono 中， 可以将 C#&amp;#160; 的委托实例传递给非托管代码， 用于替换函数指针。&amp;#160; 运行时通常会将函数指针转换， 允许非托管代码回调托管代码。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;这个转换的 Mono 中是通过 JIT 编译器实现的。 当使用 iPhone 需要的 AOT 编译器时， 有两个限制：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;回调函数必须标记为 &lt;a href="http://go-mono.com/docs/monodoc.ashx?tlink=20@ecma%3a1%23MonoPInvokeCallbackAttribute%2f" target="_blank"&gt;MonoPInvokeCallbackAttribute&lt;/a&gt;； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;回调函数必须是静态的， 现在还不支持实例函数 （这个限制以后会移除） &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;3. 没有 Remoting&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;Remoting 在 MonoTouch 上不可用。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;4. 运行时禁用的特性&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;以下特性在 iPhone 的 Mono 运行时被禁用：&lt;/p&gt;&#xD;
&#xD;
&lt;ul&gt;&#xD;
  &lt;li&gt;分析器 Profiler； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;发射 Reflection.Emit； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;发射保存 Reflection.Emit.Save； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;COM 绑定； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;JIT 引擎； &lt;/li&gt;&#xD;
&#xD;
  &lt;li&gt;元数据验证（因为没有 JIT） &lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&#xD;
&lt;p&gt;&lt;strong&gt;5. .Net API 限制&lt;/strong&gt;&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;由于不是所有东西在 iPhone 上都可用， 所以 MonoTouch 只暴露了 .Net 框架的一部分 API ， 常见问题中列举了&lt;a href="http://ios.xamarin.com/FAQ#What_.NET_features_does_MonoTouch_support.3f" target="_blank"&gt;当前支持的程序集&lt;/a&gt;。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2189767.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/09/24/2189767.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/08/30/2159448.html</id><title type="text">在MonoTouch中正确而简单的使用 Sqlite 数据库</title><summary type="text">iOS 提供了 Sqlite 作为本地数据库， MonoTouch 同样也提供了 Mono.Data.Sqlite 对 Sqlite 进行了封装。 与 Objective-c 使用 Sqlite 数据库相比， 使用 MonoTouch 进行 Sqlite 数据访问可以很简单， 先来浏览一下 Mono.Data.Sqlite 提供的类库， 有这么几个重要的类， 它们是： SqliteConnection ， 继承自 System.Data.Common.DbConnection； SqliteCommand ， 继承自 System.Data.Common.DbCommand ...</summary><published>2011-08-30T05:21:00Z</published><updated>2011-08-30T05:21:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/08/30/2159448.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/08/30/2159448.html"/><content type="html">&lt;p&gt;iOS 提供了 Sqlite 作为本地数据库， MonoTouch 同样也提供了 Mono.Data.Sqlite 对 Sqlite 进行了封装。 与 &lt;a href="http://www.iphonesdkarticles.com/2008/10/sqlite-tutorial-selecting-data.html" target="_blank"&gt;Objective-c 使用 Sqlite 数据库&lt;/a&gt;相比， 使用 MonoTouch 进行 Sqlite 数据访问可以很简单，&amp;#160; 先来浏览一下 Mono.Data.Sqlite 提供的类库， 有这么几个重要的类， 它们是：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;SqliteConnection ， 继承自 System.Data.Common.DbConnection； &lt;/li&gt;    &lt;li&gt;SqliteCommand ， 继承自 System.Data.Common.DbCommand ； &lt;/li&gt;    &lt;li&gt;SqliteDataAdapter ， 继承自 System.Data.Common.DbDataAdapter ； &lt;/li&gt;    &lt;li&gt;SqliteDataReader ， 继承自 System.Data.Common.DbDataReader ； &lt;/li&gt;    &lt;li&gt;SqliteFactory ， 继承自 System.Data.Common.DbProviderFactory ； &lt;/li&gt;    &lt;li&gt;SqliteParameter ， 继承自 System.Data.Common.DbParameter ； &lt;/li&gt;    &lt;li&gt;SqliteTransaction ， 继承自 System.Data.Common.DbTransaction ； &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;如果对这些以 Sqlite 开头的类不熟悉的话， 情有可原， 可对 System.Data.Common 下面的类应该再熟悉不过了吧， 没错， 这就是标准的 ADO.Net ， 因此只要会 ADO.Net 的开发人员， 几乎可以立即上手， 这正是 MonoTouch 对 .Net 开发人员提供的价值所在。 来看一段下面的代码：&lt;/p&gt;  &lt;pre &gt;using (var connection = SqliteFactory.Instance.CreateConnection()) {&#xD;
   connection.ConnectionString = string.Format(&amp;quot;data source={0}/northwind.db3; version=3;&amp;quot;, Environment.CurrentDirectory);&#xD;
   var command = connection.CreateCommand();&#xD;
   command.Connection = connection;&#xD;
   command.CommandText = &amp;quot;SELECT * FROM Products WHERE CategoryID = ?&amp;quot;;&#xD;
   var parameter = command.CreateParameter();&#xD;
   parameter.Value = &amp;quot;1&amp;quot;;&#xD;
   command.Parameters.Add(parameter);&#xD;
&#xD;
   connection.Open();&#xD;
   var reader = command.ExecuteReader(CommandBehavior.CloseConnection);&#xD;
   while (reader.Read()) {&#xD;
      // use reader's data here ...&#xD;
   }&#xD;
}&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt;这段代码很普通， 除了使用了一个 SqliteFactory 之外， 和 ado.net 数据访问几乎没有什么区别， 但是， 从这段代码可以看出， 我们项目原有的代码几乎可以原封不动的拿到 MonoTouch 进行编译，&amp;#160; 相信很多人都有自己对 ado.net 的封装， 如果有了 MonoTouch ， 这些封装可以很方便的移植到 MonoTouch 下。&lt;/p&gt;&#xD;
&#xD;
&lt;p&gt;最后不得不说一句， 对于 .Net 开发人员来说， MonoTouch 真的是一个好东西， 它可以让你尽快加入到 ios 的开发中， 最大限度的将你的 .net 技能延伸到 ios 。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2159448.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/08/30/2159448.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/beginor/archive/2011/08/18/2144074.html</id><title type="text">使用MonoTouch进行iOS开发</title><summary type="text">我的 MonoTouch 学习过程。</summary><published>2011-08-18T02:27:00Z</published><updated>2011-08-18T02:27:00Z</updated><author><name>张志敏</name><uri>http://www.cnblogs.com/beginor/</uri></author><link rel="alternate" href="http://www.cnblogs.com/beginor/archive/2011/08/18/2144074.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/beginor/archive/2011/08/18/2144074.html"/><content type="html">&lt;p&gt;&lt;strong&gt;开发环境准备&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;可以参考&lt;a href="http://blog.zhaojie.me/2010/09/develop-ios-app-with-monotouch-in-visual-studio-1.html" target="_blank"&gt;这篇博文&lt;/a&gt;对进行虚拟机环境配置做一下大致的了解。由于 MonoTouch 即将支持 XCode 4， 所以，推荐的开发环境为：&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;安装 OSX 10.6 ； &lt;/li&gt;    &lt;li&gt;安装 XCode 4 到 /Developer 目录， 这样可以使用 XCode 4 提供的编译工具进行编译； &lt;/li&gt;    &lt;li&gt;安装 XCode 3 到 /XCode3 目录， 这样可以使用 XCode 3 提供的独立的 Interface Builder； &lt;/li&gt;    &lt;li&gt;安装 Mono SDK For Mac OSX 的最新版本； &lt;/li&gt;    &lt;li&gt;安装 MonoTouch 的最新试用版； &lt;/li&gt;    &lt;li&gt;安装 MonoDevelop for mac osx。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;设置默认使用 Interface Builder 打开 xib 文件：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;找到任意一个 xib 文件； &lt;/li&gt;    &lt;li&gt;右键单击， 选择 Get Info； &lt;/li&gt;    &lt;li&gt;在 Info 窗口中找到 Open With， 从下拉框中选择 Interface Builder ， 点击 Change All 按钮即可。 &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;入门教程&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;objective-c 基础知识&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;进行 iOS 开发， 掌握一些 obj-c 的基础知识是必不可少的， Apple 的开发者网站上有很多关于 obj-c 的入门教程。&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;关于 obj-c 的基本概念， 可以参考 &lt;a href="http://developer.apple.com/library/ios/referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/" target="_blank"&gt;Learning Objective-C: A Primer&lt;/a&gt;， 掌握 obj-c 的一些基本概念是必须的， 比如 interface ， selector ， delegate ， property 等， 可以将这些概念和 c# 做个对比；&lt;/li&gt;    &lt;li&gt;根据 Apple 提供的教程， 使用 xcode 做一个 ios 程序， 体验一下 xcode 开发流程；&lt;/li&gt;    &lt;li&gt;能达到看着网上的 xcode 代码， 能写出相应的 C# 代码， 并能根据 C# 的特性对其进行优化；&lt;/li&gt;    &lt;li&gt;最终要求是能够将已经掌握的 C# .NET 技能延伸到 iOS 平台 。&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;开始使用 MonoTouch 进行 iOS 开发&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;网上已经有了很多 MonoTouch 的入门教程， 比如：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://blog.zhaojie.me/2010/09/develop-ios-app-with-monotouch-in-visual-studio-2.html" target="_blank"&gt;在Visual Studio中使用MonoTouch开发iOS应用程序（下）：开发体验&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://ios.xamarin.com/Tutorials" target="_blank"&gt;Xamarin 官方的 MonoTouch 教程&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://monotouch.info/" target="_blank"&gt;MonoTouch.Info&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;注意问题&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;由于苹果 SDK 的许可限制， Mono 在iOS 平台上运行于 AOT 模式， 而不是我们熟悉的 JIT 模式， 因此，需要了解什么是 &lt;a href="http://www.mono-project.com/AOT" target="_blank"&gt;aot&lt;/a&gt; 模式， 某些动态执行的代码(动态编译 Lambda 表达式， Emit, CodeDom)是不能执行的。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/beginor/aggbug/2144074.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/beginor/archive/2011/08/18/2144074.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
