存档

‘.NET’ 分类的存档

Stopping RtmpEndpoint

2010年6月5日 admin 4 条评论

服务启动后,确保没有任何客户端连接到服务器,
服务还是在20分钟后准时关闭。
2010-05-10 10:39:33,843 [2] INFO FluorineFx.Messaging.MessageServer – Stopping Message Broker
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Endpoints.RtmpEndpoint – Stopping RtmpEndpoint
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Rtmp.RtmpServer – Stopping SocketServer
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Rtmp.RtmpServer – Stopped SocketServer
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Rtmp.RtmpServer – Stopping SocketServer
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Rtmp.RtmpServer – Stopped SocketServer
2010-05-10 10:39:33,859 [2] INFO FluorineFx.Messaging.Endpoints.RtmpEndpoint – Stopped RtmpEndpoint
2010-05-10 10:39:33,859 [2] INFO FluorineFx.FluorineGateway – Stopped FluorineFx Gateway

解決方案:
应用程序池,默认空闲20分钟后关闭工作进程,修改該時間即可。

Popularity: unranked [?]

分类: .NET 标签:

我们的爱能编译通过么?

2010年5月3日 admin 1 条评论

程序员的MM们必看的广告,

想做我女朋友的也必看的广告,

微軟太有創意了

http://news.cnblogs.com/n/62747/

Popularity: unranked [?]

分类: .NET 标签:

silverlight 3D引擎 Balder

2010年2月11日 admin 没有评论
经过几个月的艰苦努力,重构代码、API以及提高性能,Balder 0.8.8.6终于发布了。这里有一个SampleBrowser Demo演示了Balder绝大多数的功能。
新特性如下:
  • 核心引入silverlight,但是仍然保持独立平台-直接在XAML中可以完成全部的工作
  • 引入View命名空间IView接口以及 Camera摄像机概念
  • Viewport有了View属性来替代了Camera
  • 从单线程改变到多线程执行,已得到更高的效率。(现在线程间的同步还有问题,有待解决)
  • 全新优化过的绘图程序
  • 原生高度图
  • 原生立方型
  • 原生圆柱型
  • 旋转、根据节点缩放
  • DebugLevel改名为DebugInfo
  • 材质系统
  • 支持对材质的高光反射
  • 支持双面材质
  • 渲染时支持Alpha通道
  • 移除在Balder.Core.Silverlight.Controls所有的控件,他们不在需要了。
  • 在Balder.Core.Silverlight.Controls中新增NodesControl控件-datadriven nodes control with templating
  • 在Balder.Core.Silverlight.Controls中新增NodesStack控件-datadriven stacking of nodes with templating
截图:

Popularity: unranked [?]

C#编辑距离算法

2010年1月15日 admin 没有评论
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace WordCompare
{
    class Program
    {
        static void Main(string[] args)
        {
            var fromString = "English is a West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.English is a West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.English is a West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.";
            var toString = "English is  West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.English is a West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.English is a West Germanic language that developed in England during the Anglo-Saxon era. As a result of the military, economic, scientific, political, and cultural influence of the British Empire during the 18th, 19th, and early 20th centuries, and of the United States since the mid 20th century,[7][8][9][10] it has become the lingua franca in many parts of the world.[11][12] It is used extensively as a second language and as an official language in Commonwealth countries and many international organisations.a";
            Stopwatch watch = new Stopwatch();
            watch.Start();
            var result = CompareStrings(fromString, toString);
            watch.Stop();
            Console.WriteLine("The result is {0}, spent {1} milliseconds.", result, watch.ElapsedMilliseconds);
        }

        private static int CompareStrings(string fromString, string toString)
        {
            var fLength = fromString.Length;
            var tLength = toString.Length;

            // pre verify the simplest condition
            if (fLength == 0)
            {
                return tLength;
            }
            if (tLength == 0)
            {
                return fLength;
            }

            // prepare the martix
            var martix = new int[fLength + 1, tLength + 1];
            for (int i = 0; i <= fLength; i++)
            {
                martix[i, 0] = i;
            }

            for (int j = 0; j <= tLength; j++)
            {
                martix[0, j] = j;
            }

            // compare the chars
            for (int i = 1; i <= fLength; i++)
            {
                var tempF = fromString[i - 1];
                var cost = 0;
                for (int j = 1; j <= tLength; j++)
                {
                    var tempT = toString[j - 1];
                    if (tempT == tempF)
                    {
                        cost = 0;
                    }
                    else
                    {
                        cost = 1;
                    }

                    var valueAbove = martix[i - 1, j] + 1;
                    var valueLeft = martix[i, j - 1] + 1;
                    // left corner
                    var valueDiag = martix[i - 1, j - 1] + cost;

                    // find the minimum from the three vars above
                    var cellValue = valueAbove < valueLeft ? (valueDiag < valueAbove ? valueDiag : valueAbove) : (valueDiag < valueLeft ? valueDiag : valueLeft);
                    martix[i, j] = cellValue;
                }
            }

            var result = martix[fLength, tLength];

            return result;
        }
    }
}


注意,有下划线的就是每个循环得到的结果。

算法证明

这个算法计算的是将s[1…i]转换为t[1…j](例如将kitten转换为sitting)所需最少的操作数(也就是所谓的编辑距离),这个操作数被保存在d[i,j](d代表的就是上图所示的二维数组)中。

  • 在第一行与第一列肯定是正确的,这也很好理解,例如我们将kitten转换为空字符串,我们需要进行的操作数为kitten的长度(所进行的操作为将kitten所有的字符丢弃)。
  • 我们对字符可能进行的操作有三种:
    • 如果我们可以使用k个操作数把s[1…i]转换为t[1…j-1],我们只需要把t[j]加在最后面就能将s[1…i]转换为t[1…j],操作数为k+1
    • 如果我们可以使用k个操作数把s[1…i-1]转换为t[1…j],我们只需要把s[i]从最后删除就可以完成转换,操作数为k+1
    • 如果我们可以使用k个操作数把s[1…i-1]转换为t[1…j-1],我们只需要在需要的情况下(s[i] != t[j])把s[i]替换为t[j],所需的操作数为k+cost(cost代表是否需要转换,如果s[i]==t[j],则cost为0,否则为1)。
  • 将s[1…n]转换为t[1…m]当然需要将所有的s转换为所有的t,所以,d[n,m](表格的右下角)就是我们所需的结果。

这个证明过程只能证明我们可以得到结果,但并没有证明结果是最小的(即我们得到的是最少的转换步骤)。所以我们引进了另外一个算法,即d[i,j]保存的是上述三种操作中操作数最小的一种。这就保证了我们获得的结果是最小的操作数(可使用argument by contradiction进行证明,离题太远,忽略。。)

可能进行的改进

  • 现在的算法复杂度为O(mn),可以将其改进为O(m)。因为这个算法只需要上一行和当前行被存储下来就可以了。
  • 如果需要重现转换步骤,我们可以把每一步的位置和所进行的操作保存下来,进行重现。
  • 如果我们只需要比较转换步骤是否小于一个特定常数k,那么只计算高宽宽为2k+1的矩形就可以了,这样的话,算法复杂度可简化为O(kl),l代表参加对比的最短string的长度。
  • 我们可以对三种操作(添加,删除,替换)给予不同的权值(当前算法均假设为1,我们可以设添加为1,删除为0,替换为2之类的),来细化我们的对比。
  • 如果我们将第一行的所有cell初始化为0,则此算法可以用作模糊字符查询。我们可以得到最匹配此字符串的字符串的最后一个字符的位置(index number),如果我们需要此字符串的起始位置,我们则需要存储各个操作的步骤,然后通过算法计算出字符串的起始位置。
  • 这个算法不支持并行计算,在处理超大字符串的时候会无法利用到并行计算的好处。但我们也可以并行的计算cost values(两个相同位置的字符是否相等),然后通过此算法来进行整体计算。
  • 如果只检查对角线而不是检查整行,并且使用延迟验证(lazy evaluation),此算法的时间复杂度可优化为O(m(1+d))(d代表结果)。这在两个字符串非常相似的情况下可以使对比速度速度大为增加。

Popularity: unranked [?]

分类: .NET 标签:

C# A*寻路算法

2010年1月15日 admin 1 条评论
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Drawing;
  5.  
  6. namespace PathFinder
  7. {
  8. public class PathFinder
  9. {
  10. private PathNode startNode, endNode, currentNode;//开始点、终点、当前节点
  11. private byte[,] map;//矩阵地图0表示可行、1表示障碍物
  12. private List closePath, openPath;//  关闭列表、开启列表
  13. private List bestPaht;//最终保存最佳路径
  14. private bool findSuccess = false;//是否寻路成功
  15. /**////
  16. /// 开始寻路
  17. ///
  18. /// 二维地图矩阵         /// 开始坐标点         /// 终点         ///
  19. public List FindBestPaht(byte[,] map, Point startPoint, Point endPoint)
  20. {
  21. closePath = new List();
  22. openPath = new List();
  23. bestPaht = new List();
  24. this.map = map;
  25. startNode = new PathNode(startPoint.X, startPoint.Y);
  26. startNode.ParentPoint = new Point(-1, -1);
  27. endNode = new PathNode(endPoint.X, endPoint.Y);
  28. currentNode = startNode;//开始节点设置为默认当前节点
  29. currentNode.ParentG = currentNode.G = 0;
  30. openPath.Add(startNode);//添加到开启列表
  31. TryToFindPaht(startNode);//开始寻找路径
  32. if (findSuccess)
  33. {
  34. InsertPahtNode(endNode);//如果寻找成功,则从终点开始从关闭列表中把最近路径添加到最佳路径列表
  35. return bestPaht;
  36. }
  37. else
  38. return null;
  39. }
  40. /**////
  41. /// 尝试寻路
  42. ///
  43. /// 开始节点         private void TryToFindPaht(PathNode node)
  44. {
  45. if (openPath.Count &gt; 0)
  46. {
  47. closePath.Add(openPath[0]);//每次从开启列表中取第一个添加到关闭列表,注意这个列表已经是排序后的,第一个既是F值最小的
  48. openPath.RemoveAt(0);//把该节点从开启列表中移除
  49. }
  50. AddOpenNode(node);//以这个节点为基准,把它四周的节点添加到开启列表中,排除障碍物、已经在开启列表或关闭列表中的
  51. //当目标节点已经在开启列表中时表示寻路成功
  52. if (IsInOpenPaht(endNode))
  53. {
  54. closePath.Add(endNode);//将目标节点添到关闭列表中
  55. endNode.ParentPoint = currentNode.Point;//目标节点的父节点为当前节点
  56. findSuccess = true;
  57. return;
  58. }
  59. SortPathByF();//按F值从小到大排序
  60. if (openPath.Count &gt; 0)
  61. {
  62. currentNode = openPath[0];//从开启列表中取F值最小的作为当前节点
  63. TryToFindPaht(currentNode);//递归调用,再次寻路
  64. }
  65. }
  66. /**////
  67. /// 把当前节点四周的八个节点尝试全部添加到开启列表中
  68. ///
  69. /// 当前节点         private void AddOpenNode(PathNode node)
  70. {
  71. AddOneOpenNode(node.X, node.Y + 1, node.Point);
  72. AddOneOpenNode(node.X, node.Y - 1, node.Point);
  73. AddOneOpenNode(node.X + 1, node.Y, node.Point);
  74. AddOneOpenNode(node.X - 1, node.Y, node.Point);
  75. AddOneOpenNode(node.X - 1, node.Y - 1, node.Point);
  76. AddOneOpenNode(node.X - 1, node.Y + 1, node.Point);
  77. AddOneOpenNode(node.X + 1, node.Y + 1, node.Point);
  78. AddOneOpenNode(node.X + 1, node.Y - 1, node.Point);
  79. }
  80. /**////
  81. /// 添加一个新节点到开启列表中
  82. ///
  83. /// 新节点X坐标         /// 新节点Y坐标         /// 父节点坐标         private void AddOneOpenNode(int x, int y, Point point)
  84. {
  85. PathNode node = new PathNode(x, y);
  86. //添加前提是:x、y在当前地图二维矩阵范围内、且是可行路径、不再关闭列表中也不再开启列表中
  87. if (x &gt;= 0 &amp;&amp; y &gt;= 0 &amp;&amp; x &lt;= map.GetUpperBound(1) &amp;&amp; y &lt;= map.GetUpperBound(0) &amp;&amp; map[y, x] == 0 &amp;&amp; !IsInClosePaht(node) &amp;&amp; !IsInOpenPaht(node))
  88. {
  89. node.X = x;
  90. node.Y = y;
  91. node.ParentPoint = point;// 新节点的父节点为当前节点
  92. node.ParentG = currentNode.G;//记录新节点的父节点G值、以便与当前节点做比较
  93. node.G = (currentNode.X == node.X || currentNode.Y == node.Y ? 10 : 14) + node.ParentG;//当前节点的G值为父节点G值+10(非对角线)或14 (对角线)
  94. node.H = 10 * (Math.Abs(endNode.X - node.X) + Math.Abs(endNode.Y - node.Y));//更新H值
  95. openPath.Add(node);
  96. }
  97. }
  98. /**////
  99. /// 从关闭列表中,从目标点开始倒着查找所有父节点并将其添加到最佳路径中
  100. ///
  101. ///          private void InsertPahtNode(PathNode node)
  102. {
  103. bestPaht.Insert(0, node.Point);
  104. foreach (PathNode item in closePath)
  105. {
  106. if (item.Point == node.ParentPoint)
  107. InsertPahtNode(item);
  108. }
  109. }
  110. /**////
  111. /// 按F值从小到大排序
  112. ///
  113. private void SortPathByF()
  114. {
  115. for (int i = 0; i &lt; openPath.Count; i++)
  116. {
  117. for (int j = 0; j &lt; openPath.Count - i - 1; j++)
  118. {
  119. if (openPath[j].F &gt; openPath[j + 1].F)
  120. {
  121. PathNode temp = openPath[j + 1];
  122. openPath[j + 1] = openPath[j];
  123. openPath[j] = temp;
  124. }
  125. }
  126. }
  127. }
  128. /**////
  129. /// 判断某个阶段是否在关闭列表中
  130. ///
  131. ///      ///
  132. private bool IsInClosePaht(PathNode node)
  133. {
  134. foreach (PathNode item in closePath)
  135. {
  136. if (item.X == node.X &amp;&amp; item.Y == node.Y)
  137. return true;
  138. }
  139. return false;
  140. }
  141. /**////
  142. /// 判断某个节点是否在开启列表中
  143. ///
  144. ///          ///
  145. private bool IsInOpenPaht(PathNode node)
  146. {
  147. foreach (PathNode item in openPath)
  148. {
  149. if (item.X == node.X &amp;&amp; item.Y == node.Y)
  150. return true;
  151. }
  152. return false;
  153. }
  154. }
  155. /**////
  156. /// 定义节点类
  157. ///
  158. public class PathNode
  159. {
  160. public PathNode(int x, int y)
  161. {
  162. this.X = x;
  163. this.Y = y;
  164. }
  165. /**////
  166. /// 节点坐标
  167. ///
  168. public Point Point { get { return new Point(X,Y); } }
  169. /**////
  170. ///  父节点坐标
  171. ///
  172. public Point ParentPoint { get; set; }
  173. /**////
  174. /// X坐标点
  175. ///
  176. public int X { get; set; }
  177. /**////
  178. /// Y坐标点
  179. ///
  180. public int Y { get; set; }
  181. /**////
  182. /// F值=G+H
  183. ///
  184. public int F { get { return G + H; } }
  185. /**////
  186. /// G值,即从起始节点到当前节点的距离,直线规定为10,对角线规定为14
  187. ///
  188. public int G { get; set; }
  189. /**////
  190. /// 从当前节点到目标节点纵向坐标距离和横向坐标距离之和
  191. ///
  192. public int H { get; set; }
  193. /**////
  194. /// 该节点父节点的G值
  195. ///
  196. public int ParentG { get; set; }
  197. }
  198. }

Popularity: unranked [?]

分类: .NET 标签:

Silverlight 3 发布

2009年7月10日 admin 没有评论

BANGF892E17712587E851CAC239BXIANGUO
image

Visual Studio 2008 SP1 的Silverlight3主要包括如下功能:

  • Visual Basic and C# Project templates
  • Intellisense and code generators for XAML
  • Debugging of Silverlight applications
  • Remote debugging of Silverlight applications for Mac
  • Web reference support
  • WCF Templates
  • Team Build and command line build support
  • Support for cached transparent platform extensions
  • Support for Silverlight 3 Out-of-Browser applications

到了Silverlight3也计划有时间开始了解Silverlight了。下面是相关的link:

Popularity: unranked [?]

由于另一个程序或正在运行的服务可能正在使用网络地址转换组件(Ipnat.sys)

2009年6月9日 admin 没有评论

今天在服务器上遇到了这个问题,在CSDN上也没找到解决方法,

后来自己解决了,步骤如下:

1, 开始–>管理工具–>服务 找到Windows Firewall/Internet Connection Sharing (ICS) 并启动这个服务

2,开始–>控制面板–>Windows防火墙   启动就可以了.

Popularity: 10% [?]

彻底解决 Visual Studio 在 Vista 和 Windows7无法调试

2009年6月3日 admin 没有评论

解决步骤:

开始-运行(win+R),在此键入:c:\windows\system32\drivers\etc\hosts

然后:选择记事本或其实字本编辑器打开。打开后你会发现有这么两行代码;

127.0.0.1       localhost
::1                localhost

将第二行::1后面的localhost去掉或注释掉就解决问题了。

最后是这样的:

127.0.0.1       localhost
::1

修改完毕后,保存该文件,重新运行VS2008调试程序。问题解决。

Popularity: 7% [?]

什么是序列化

2009年4月17日 admin 没有评论

什么是序列化?
  .net的运行时环境用来支持用户定义类型的流化的机制。它是将对象实例的状态存储到存储媒体的过程。在此过程中,先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,然后再把字节流写入数据流。在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

序列化的目的:
  1、以某种存储形式使自定义对象持久化;
  2、将对象从一个地方传递到另一个地方。
  
  实质上序列化机制是将类的值转化为一个一般的(即连续的)字节流,然后就可以将该流写到磁盘文件或任何其他流化目标上。而要想实际的写出这个流,就要使用那些实现了IFormatter接口的类里的Serialize和Deserialize方法。
  在.net框架里提供了这样两个类:
  
  一、BinaryFormatter
  
  BinaryFormatter使用二进制格式化程序进行序列化。您只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象实例作为参数提供给此调用。类中的所有成员变量(甚至标记为 private 的变量)都将被序列化。
  
  首先我们创建一个类:
  [Serializable]
  public class MyObject {
   public int n1 = 0;
   public int n2 = 0;
   public String str = null;
  }
  Serializable属性用来明确表示该类可以被序列化。同样的,我们可以用NonSerializable属性用来明确表示类不能被序列化。
  接着我们创建一个该类的实例,然后序列化,并存到文件里持久:
  MyObject obj = new MyObject();
  obj.n1 = 1;
  obj.n2 = 24;
  obj.str = “一些字符串”;
  IFormatter formatter = new BinaryFormatter();
  Stream stream = new FileStream(”MyFile.bin”, FileMode.Create,
  FileAccess.Write, FileShare.None);
  formatter.Serialize(stream, obj);
  stream.Close();
  
  而将对象还原到它以前的状态也非常容易。首先,创建格式化程序和流以进行读取,然后让格式化程序对对象进行反序列化。
  IFormatter formatter = new BinaryFormatter();
  Stream stream = new FileStream(”MyFile.bin”, FileMode.Open,
  FileAccess.Read, FileShare.Read);
  MyObject obj = (MyObject) formatter.Deserialize(fromStream);
  stream.Close();
  
  // 下面是证明
  Console.WriteLine(”n1: {0}”, obj.n1);
  Console.WriteLine(”n2: {0}”, obj.n2);
  Console.WriteLine(”str: {0}”, obj.str);
  
  二、SoapFormatter
  
  前面我们用BinaryFormatter以二进制格式来序列化。很容易的我们就能把前面的例子改为用SoapFormatter的,这样将以xml格式化,因此能有更好的可移植性。所要做的更改只是将以上代码中的格式化程序换成 SoapFormatter,而 Serialize 和 Deserialize 调用不变。对于上面使用的示例,该格式化程序将生成以下结果。
  
      xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
   xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
   xmlns:SOAP- ENC=http://schemas.xmlsoap.org/soap/encoding/
   xmlns:SOAP- ENV=http://schemas.xmlsoap.org/soap/envelope/
   SOAP-ENV:encodingStyle=
   “http://schemas.microsoft.com/soap/encoding/clr/1.0
   http://schemas.xmlsoap.org/soap/encoding/”
   xmlns:a1=”http://schemas.microsoft.com/clr/assem/ToFile”>
 
  在这里需要注意的是,无法继承 Serializable 属性。如果从 MyObject 派生出一个新的类,则这个新的类也必须使用该属性进行标记,否则将无法序列化。例如,如果试图序列化以下类实例,将会显示一个 SerializationException,说明 MyStuff 类型未标记为可序列化。
  
  public class MyStuff : MyObject
  {
   public int n3;
  }
  
  然而关于格式化器,还有个问题,假设我们只需要xml,但不需要soap特有的额外信息,那么该怎么做?有两个方案:1、编写一个实现IFormatter接口的类,采用的方式类似于SoapFormatter,但是可以没有你不需要的信息;2、使用框架提供的类XmlSerializer。
  XmlSerializer类和前两个主流的序列化类的几个不同点是:
  1、不需要Serializable属性,Serializable和NonSerializable属性将会被忽略,但是使用XmlIgnore属性,和NonSerializable属性类似。
  2、该类不能安全地访问私有变成员,所以学要将私有成员改为公共成员,或者提供合适的公共特性。
  3、要求被序列化的类要有一个默认的构造器。
  
  我们改一下前面的MyObject类为:
  
  public class MyObject {
   public int n1;
   public String str;
   public MyObject(){}
   public MyObject(n1,str)
   {
   this.n1=n1;
   this.str=str;
   }
   public override string ToString()
   {
   return String.Format(”{0}:{1}”,this.str,this.n1);
   }
  }
  
  现在我们用XmlSerializer类来对修改后的MyObject进行序列化。因为XmlSerializer类的构造器里有个Type参数,所以XmlSerializer对象被明确的 连到该Type参数所表示的类了。XmlSerializer类也有Serialize和Deserialize方法:
  MyObject obj = new MyObject(12,”some string…”);
  XmlSerializer formatter = new XmlSerializer(typeof(MyObject));
  Stream stream = new FileStream(”MyFile.xml”, FileMode.Create,
  FileAccess.Write, FileShare.None);
  formatter.Serialize(stream, obj);
  //下面是反序列化
  stream.Seek(0,SeekOrigin.Begin)
  MyObject obj_out=(MyObject)formatter.Deserialize(stream)
  stream.Close();
  Console.WriteLine(obj_out);
  
  这个简单的列子可以加以扩展,以便利用更多的XmlSerializer功能,包括使用属性控制xml标记、使用xml模式和进行soap编码。
  
  自定义序列化
  
  如果你希望让用户对类实现序列化,但是对数据流的组织方式不完全满意,那么可以通过在对象上实现 ISerializable 接口来自定义序列化过程。这一功能在反序列化后成员变量的值失效时尤其有用,但是需要为变量提供值以重建对象的完整状态。除了必须将类申明为 Serializable 的同时,还要要实现 ISerializable接口,需要实现 GetObjectData 方法以及一个特殊的构造函数,在反序列化对象时要用到此构造函数。在实现 GetObjectData 方法时,最常调用的SerializationInfo的方法是AddValue,这个方法具有针对所有标准类型(int、char等等)的重载版本;而 StreamingContext 参数描述给定的序列化流的源和目标,这样我们就可以知道我们是将对象序列化到持久性存储还是在将他们跨进程或机器序列化。而在反序列化时,我们调用SerializationInfo提供的一组Getxxx方法,他们针对所有标准类型数据执行各种AddValue重载版本的逆操作。下代码示例说明了如何在前一部分中提到的 MyObject 类上实现 ISerializable。
  
  [Serializable]
  public class MyObject : ISerializable
 {
   public int n1;
   public int n2;
   public String str;
  
   public MyObject()
   {
   }
  
   protected MyObject(SerializationInfo info, StreamingContext context)
   {
   n1 = info.GetInt32(”i”);
   n2 = info.GetInt32(”j”);
   str = info.GetString(”k”);
   }
  
   public virtual void GetObjectData(SerializationInfo info,
  StreamingContext context)
   {
   info.AddValue(”i”, n1);
   info.AddValue(”j”, n2);
   info.AddValue(”k”, str);
   }
    }
  在序列化过程中调用 GetObjectData 时,需要填充方法调用中提供的 SerializationInfo 对象。只需按名称/值对的形式添加将要序列化的变量。其名称可以是任何文本。只要已序列化的数据足以在反序列化过程中还原对象,便可以自由选择添加至 SerializationInfo 的成员变量。如果基对象实现了 ISerializable,则派生类应调用其基对象的 GetObjectData 方法。
    
  需要强调的是,将 ISerializable 添加至某个类时,需要同时实现 GetObjectData 以及特殊的具有特定原型的构造函数--重要的是,该构造函数的参数列表必须与GetObjectData相同,这个构造函数将会在反序列化的过程中使用:格式化器从流中反序列化数据,然后通过这个构造函数对对象进行实列化。如果缺少 GetObjectData,编译器将发出警告。但是,由于无法强制实现构造函数,所以,缺少构造函数时不会发出警告。如果在没有构造函数的情况下尝试反序列化某个类,将会出现异常。在消除潜在安全性和版本控制问题等方面,当前设计优于 SetObjectData 方法。例如,如果将 SetObjectData 方法定义为某个接口的一部分,则此方法必须是公共方法,这使得用户不得不编写代码来防止多次调用 SetObjectData 方法。可以想象,如果某个对象正在执行某些操作,而某个恶意应用程序却调用此对象的 SetObjectData 方法,将会引起一些潜在的麻烦。
  
  在反序列化过程中,使用出于此目的而提供的构造函数将 SerializationInfo 传递给类。对象反序列化时,对构造函数的任何可见性约束都将被忽略,因此,可以将类标记为 public、protected、internal 或 private。一个不错的办法是,在类未封装的情况下,将构造函数标记为 protect。如果类已封装,则应标记为 private。要还原对象的状态,只需使用序列化时采用的名称,从 SerializationInfo 中检索变量的值。如果基类实现了 ISerializable,则应调用基类的构造函数,以使基础对象可以还原其变量。
  
  如果从实现了 ISerializable 的类派生出一个新的类,则只要新的类中含有任何需要序列化的变量,就必须同时实现构造函数以及 GetObjectData 方法。以下代码片段显示了如何使用上文所示的 MyObject 类来完成此操作。
  
  [Serializable]
  public class ObjectTwo : MyObject
  {
   public int num;
  
   public ObjectTwo() : base(){ }
  
   protected ObjectTwo(SerializationInfo si, StreamingContext context) : base(si,context)
   {
   num = si.GetInt32(”num”);
   }
  
   public override void GetObjectData(SerializationInfo si, StreamingContext context)
   {
   base.GetObjectData(si,context);
   si.AddValue(”num”, num);
   }
  }
  切记要在反序列化构造函数中调用基类,否则,将永远不会调用基类上的构造函数,并且在反序列化后也无法构建完整的对象。
  
  对象被彻底重新构建,但是在反系列化过程中调用方法可能会带来不良的副作用,因为被调用的方法可能引用了在调用时尚未反序列化的对象引用。如果正在进行反序列化的类实现了 IDeserializationCallback,则反序列化整个对象图表后,将自动调用 OnSerialization 方法。此时,引用的所有子对象均已完全还原。有些类不使用上述事件侦听器,很难对它们进行反序列化,散列表便是一个典型的例子。在反序列化过程中检索关键字/值对非常容易,但是,由于无法保证从散列表派生出的类已反序列化,所以把这些对象添加回散列表时会出现一些问题。因此,建议目前不要在散列表上调用方法。 

Popularity: 15% [?]

分类: .NET 标签:

Microsoft Visual Studio 遇到了问题,需要关闭

2009年4月16日 admin 没有评论

很多人遇到这个问题, 可是在GOOGLE中找到的答案都不适合自己,

以下是我的解决方法希望对大家有所帮助:

1 ,  打VS2008的 SP1 补丁

2, 升级 VS2008 (用正版注册码升级,我的另外一篇文章有正版注册码及相关介绍 点击查看)

3, 重启 电脑

Popularity: 18% [?]