什么是最有价值的.Net Compact Framework提示,技巧和想法 - 避免者?

时间:2008-12-12 15:54:47

标签: .net windows-mobile compact-framework

我们在.Net Compact Framework和Windows Mobile中广泛开展工作。我已经看到很多关于ASP.Net应用程序或其他.Net桌面应用程序开发细节的问题,但没有特定的CF.

其他任何移动开发人员都可以分享一些事情来开始做,停止做,并避免在Compact Framework中进行开发时做什么?

14 个答案:

答案 0 :(得分:120)

不确定

  • 尽可能使用物理设备(不是模拟器)
  • 使用多个设备(不同供应商,不同型号)进行测试
  • 围绕睡眠/唤醒行为进行集中测试
  • 使用MSTEST单元测试时,请勿使用私人访问者
  • 避免像瘟疫一样的ActiveSync - 使用CoreCon direct调试
  • 熟悉RPM并尽早开始使用
  • 尽可能重用对象
  • 避免在Form的ctor中做很多工作 - 为延迟加载或在后台线程中加载它
  • 尽可能按需加载表单(不是一次全部加载)
  • 缓存常用表单,按需创建不常用的表单
  • 保持较低的图像分辨率
  • 如果某个类公开Dispose 使用它。总是。
  • 没有应用程序太小,无法从MVC / MVP模式中受益
  • 不要使用Microsoft CAB / SCSF端口用于CF(移植它的人显然从未实际使用过资源有限的设备)。
  • 如果您要进行任何远程数据/服务活动,请熟悉“偶尔连接”的概念
  • Docking和Anchoring是你的朋友和你的敌人 - 测试运行时屏幕轮换和多个分辨率(即使你认为你不会瞄准它们,因为你可能在这个想法中错了)
  • 请注意,但不要大量投资设备部署包项目类型。它有很大的局限性可能会让你感到困惑。批处理文件工作得非常好,或者自定义MSBUILD任务调用CabWiz
  • 了解您的C ++和P / Invoke技能。您需要它们。在没有P / Invoking的情况下编写有用的CF应用程序几乎是不可能的。
  • 代码为目标的最低公分母。
  • 部分类是您的朋友,特别是在目标类型(PPC,电话,非移动CE)之间划分逻辑。
  • 避免从持久存储中运行应用程序,尤其是CE和WInMo之前的应用程序5.复制到RAM并从那里运行以防止请求分页导致您死亡,尤其是在睡眠/唤醒周期之后。
  • 应用程序不应该关心睡眠/唤醒转换,但那是纯粹的理论。睡眠唤醒**将*改变你的应用行为,所以再次测试,测试,测试。
  • 我提到过测试吗?特别是在每个设备上你都可以得到你的手吗?从您的测试实验室购买eBay的廉价硬件。除非您打算使用较新设备的特定功能,否则拥有更多设备比拥有最新设备更重要。
  • 如果您打算以编程方式使用蓝牙,请求神圣干预。熟悉Widcomm和Microsoft堆栈,并了解它们不一样。
  • 观看Compact Framework中有关内存管理的MSDN网络广播。再次观看你第一次错过的东西。
  • 注意睡眠/唤醒使内部句柄无效并导致访问冲突。这更为深奥,但肯定会发生。例如,如果您正在从存储卡运行应用程序,则整个应用程序不会加载到RAM中。正在使用的片段被请求分页以供执行。这一切都很好。现在,如果关闭设备,驱动程序全部关闭。重新启动电源时,许多设备只需重新安装存储设备即可。当你的应用程序需要在更多程序中请求页面时,它不再是它的位置而且它会消失。安装的商店中的数据库可能会发生类似的行为如果您有一个打开的数据库句柄,则在睡眠/唤醒周期后,连接句柄可能不再有效。
  • 安装evaluation version of Platform Builder。许多东西的源代码都在那里(比如网络用户界面,许多驱动程序等),当你的P / Invoke代码没有按照你的预期进行时,你至少可以找到一个去寻找的地方。 “为什么”。

已添加5/25/10

已添加7/27/10

  • 如果您正在使用审美UI,请准备好进行大量自定义或手动绘图。
  • 如果您正在进行自定义或手动绘图,并且需要使用透明度,请准备好加载frustrations并且必须写wacky code或直接致电native code work around CF中的3}} shortcomings

已添加11/22/11

我只是添加到列表中,因为它们发生在我身上......

答案 1 :(得分:13)

OpenNETCF是一个很好的资源。

在使用.NET Compact Framework进行开发时,他们的Smart Device Framework是必不可少的,因为缺少许多Full框架功能[我认为有人曾经说过.NET Compact Framework是NotImplementedException的包装器! ]

答案 2 :(得分:11)

这不是 Compact Framework设备所特有的,但是由于在移动平台上开发资源限制而在开发它们时,它会变得更加丑陋。


最近,我发现了一篇很棒的帖子,作为管理内存泄漏的一部分,帮助我在一个移动应用程序中bug when setting the DataGrid.DataSource找出了我不知道的泄漏。

绑定DataGrid时,应直接使用以下内容:

dgDataGrid.DataSource = dsDataSet;

因为这会在每次没有正确处理时创建一个新的CurrencyManager。相反,您希望首先将DataGrid绑定到BindingSource,以避免资源泄漏。

bsData.DataSource = dsDataSet;

dgDataGrid.DataSource = bsData;

谁知道?斯科特朗廷在another post做了。谢谢斯科特!

答案 3 :(得分:7)

正如您所看到的那样,如果您对在Visual Studio 2010中没有Compact Framework支持感到不满,请转到here并投票支持将其添加进去。(并传播该词)

MS或多或少放弃了Connect中的现有功能请求。有关此功能,请转到新的User Voice site to vote

答案 4 :(得分:7)

如果您必须支持多种屏幕尺寸/分辨率,表单继承是一种很好的方法。基本上,您设计的表格适合标准的320x240屏幕。要支持不同的屏幕大小,您只需添加一个新表单,从您的自定义表单(而不仅仅是表单)继承,然后根据需要重新排列控件。

另一个有用的技巧是以一种允许您将父表单的标题临时设置为“”的方式包装ShowDialog调用 - 这会使应用程序中的所有打开表单不会显示在正在运行的程序列表中。增强包装器的另一种方法是使用父窗口的句柄PInvoke SetForegroundWindow。这可以确保父母在孩子关闭后总是重新出现;没有这个调用,其他窗口可以插入父窗体上方的z-stack中。

注意SD卡上的加密。 SqlCE将完全停止工作。 Oracle Lite在加密下的行为更加险恶,因为它的部分功能和部分功能都不起作用。

避免使用SqlCE RDA并合并复制。如果它们可靠地工作,这些将是很棒的工具,但是在复制期间可能意外地丢弃网络连接的情况下(在WM世界中很常见)。这一点我很难与生产应用程序。我们处理的MS支持技术最终被迫承认它不能100%工作。实际引用:“只是继续尝试复制 - 它们最终会正确合并”。

答案 5 :(得分:7)

大多数不同寻常的东西需要通过P / Invoke直接调用Windows API。 我发现http://www.pinvoke.net/是Win32和Windows CE上P / Invoke的绝佳资源。

答案 6 :(得分:4)

使用Compact Framework和SqlCe,可能会出现很多性能,内存泄漏和线程同步问题。

遵守最小化Compact Framework的规则 - SqlCe令人头疼。

  1. 使用一个SqlCe连接 - 您可以在连接上使用锁定机制,以便在多个线程上使用一个连接。
  2. 由于Sqlce引擎,批量数据插入很慢。使用直接表插入,与直接写入文本文件具有类似的性能优势。
  3. 在应用程序关闭时配置SqlCe连接。这样可以确保清理所有资源。
  4. 每次调用数据库后,都要处理所有命令,数据引导程序等。使用语句是你的朋友。使用语句等确保阅读器对象在命令内...

答案 7 :(得分:4)

  • 如果您打算使用Sql Server 3.5 Compact,请阅读this blog
  • SQL Server Compact存在严重的性能问题,与桌面相比,设备上的某些代码可能会慢100倍,因此请始终在设备上测试数据库代码。
  • 设备上的设置单元和性能/集成测试。实际上也很少有人这样做,它并不复杂,远远超过了成本。
  • 如果您始终使用网络而不是ActiveSync部署代码。最简单的方法是在设备上设置一个简单的FTP服务器或TCP代理。

答案 8 :(得分:3)

单元测试(TDD)可以在.net cf.但是有一些问题。

您将使用MSTest。不是NUnit,MBUnit,XUnit.net等MSTest。

您将需要Visual Studio Professional(尽我所知)。最简单的入门方法是右键单击要测试的方法,然后选择“创建单元测试”。这为您设置了测试项目。只创建一个测试项目。它不喜欢有多个。只需执行此操作即可创建项目并为您设置所有依赖项。然后创建自己的测试类。

模拟对象可能是个问题。 RhinoMocks,Moq和TypeMock都依赖于.net cf中没有的东西。 Pex有一个项目叫做Stubs,我还在调查。 Pex是Microsoft Research的一个项目。您将最终创建自定义假对象。

测试在设备模拟器上运行。这意味着必须部署它们。如果您在第一次启动测试运行器时遇到奇怪的错误,那么您可能还没有在设备模拟器上安装.net 3.5。首先部署项目,然后再次运行测试。

在非测试方面: 你确实得到LINQ to Objects和LINQ to XML。两者都是天赐之物。 您可以通过WCF与服务器通信,但是您没有获得所有端点。

答案 9 :(得分:3)

OpenNet CF值得研究 - 即使免费版也有一些有用的库 - 例如FTP,datagrid附加功能等;这非常有用,因为CF缺少很多.net框架功能。

答案 10 :(得分:2)

  • 您将在.net cf.中遇到很多错误和限制。你将不得不修补它们。它很丑,但你别无选择。

  • 您最终会编写很多自定义控件。由于框架中的大多数控件不支持客户端通常请求的功能。因此,为您从一开始就使用的每个控件创建自定义控件是一个很好的做法。即使你开始时可能没有任何东西。您可以稍后添加自定义逻辑。无需修改大量现有代码。

  • 如果您需要验证,可以使用.net validation framework

  • 在您的应用程序中随处可见代码是一个好主意。您可以使用MVC模式。如果您选择使用它,您可以使用MobileMVC
  • 开始
  • 如果您需要丰富的UI工具包,可以查看Resco(谷歌)。
  • VS Designer将成为你的主要敌人。

这就是我现在能想到的一切。

答案 11 :(得分:2)

使用DataGrid时,您可以使用以下代码posted on Chris Craft's blog通过列标题对其内容进行排序:

using System.Windows.Forms;
using System.Data;

public static void SortDataGrid(object sender, System.Windows.Forms.MouseEventArgs e)
{
   DataGrid.HitTestInfo hitTest;
   DataTable dataTable;
   DataView dataView;
   string columnName;
   DataGrid dataGrid;

   // Use only left mouse button clicks.
   if (e.Button == MouseButtons.Left)
   {
   // Set dataGrid equal to the object that called this event handler.
   dataGrid = (DataGrid)sender;

   // Perform a hit test to determine where the mousedown event occured.
   hitTest = dataGrid.HitTest(e.X, e.Y);

   // If the MouseDown event occured on a column header,
   // then perform the sorting operation.
   if (hitTest.Type == DataGrid.HitTestType.ColumnHeader)
   {
      // Get the DataTable associated with this datagrid.
      dataTable = (DataTable)dataGrid.DataSource;

      // Get the DataView associated with the DataTable.
      dataView = dataTable.DefaultView;

      // Get the name of the column that was clicked.
      if(dataGrid.TableStyles.Count != 0)
         columnName = dataGrid.TableStyles[0].GridColumnStyles[hitTest.Column].MappingName;
      else
         columnName = dataTable.Columns[hitTest.Column].ColumnName;

      // If the sort property of the DataView is already the current
      // column name, sort that column in descending order.
      // Otherwise, sort on the column name.
      if (dataView.Sort == columnName)
         dataView.Sort = columnName + " DESC";
      else
         dataView.Sort = columnName;
      }
   }
}

private void dgDataGrid_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
{
   if(dgDataGrid.VisibleRowCount == 0) return;
   SortDataGrid(sender, e);
   dgDataGrid.Select(dgDataGrid.CurrentRowIndex);
}

答案 12 :(得分:1)

使用Windows Mobile时,如果您不希望全屏显示表单,则需要将 FormBorderStyle 设置为。如果你不这样做,你会花几个小时拉出你的头发,想知道为什么它会自动调整到全屏大小(实际上是Windows Mobile的功能

答案 13 :(得分:1)

使用OutlookSession执行任何操作时,始终

  • 在主(应用程序)线程上实例化它
  • 在主线程上执行它 (我使用Control对象来调用 靠)
  • 并将其处理得体面 时间表(如果你没有,你会有 Pocket Outlook中的奇怪行为)