posts - 15,  comments - 19,  trackbacks - 0

这短时间一直在弄持久化服务。因为对SQL2000会一些。所以打算用SqlWorkflowPersistenceService。

可以弄来弄去,发现怎么也不对啊?

查阅了代码,发现代码没有错。。。

一直弄了好些日子,也请教了一些人,可是问题依旧。。。

 

今天照例继续检查我的代码
我在检查代码的时候查阅了资料,如果要用sql2000的SqlWorkflowPersistenceService服务必须满足两个条件,一个是必须安装SP4,另外一个就是需要开启MSDTC服务。
检查我的机器后发现,虽然安装了SP4,但是MSDTC服务却启动不正常,于是安装了MSDTC服务,然后重新启动,终于看见我的WORKFLOW实例保存到SQL2000中去啦。

另外,如果有防火墙,一定要开放105端口和SYSTEM32\MSDTC.EXE

 

我的MSDTC出了问题,再付上解决方法。。。。

 

setp 1服务
MSDTC_1.bat
@echo off
if {%1}=={} @echo Syntax: MSDTC1 Filename&goto :EOF
setlocal ENABLEDELAYEDEXPANSION
set filename=%1
if exist %filename% del /q %filename%
(
@echo Alerter
@echo EventSystem
@echo Browser
@echo TrkWks
@echo Dnscache
@echo Eventlog
@echo PolicyAgent
@echo dmserver
@echo Messenger
@echo Netlogon
@echo NtLmSsp
@echo Netman
@echo PlugPlay
@echo RpcSs
@echo RpcLocator
@echo NtmsSvc
@echo SamSs
@echo lanmanserver
@echo SENS
@echo Schedule
@echo LmHosts
@echo winmgmt
@echo Wmi
@echo W32Time
@echo lanmanworkstation
)>"%TEMP%"MSDTC1.TMP"
call :stopdtc>nul 2>&1
for /f "Tokens=*" %%L in ('reg query HKLM"System"CurrentControlSet"Services^|FINDSTR /I /B /L /C:"HKEY_LOCAL_MACHINE"') do (
set line=%%L
set key=HKLM!LINE:~18!
call :subkey "!key!"
call :testsvc
)
endlocal
goto :EOF
:stopdtc
sc stop msdtc
goto :EOF
:testsvc
for /f "Tokens=*" %%c in ('@echo !svc!^|findstr /I /B /E /L /G:"%TEMP%"MSDTC1.TMP"') do goto :EOF
set /a start=3
set /a type=0
call :getstart>nul 2>&1
call :gettype>nul 2>&1
if %type% LSS 16 goto :EOF
if %start% NEQ 2 goto :EOF
sc config !svc! start= demand
@echo sc config !svc! start= auto>>%filename%
goto :EOF
:gettype
for /f "Tokens=2,3" %%x in ('reg query "HKLM"System"CurrentControlSet"Services"!svc!" /V type^|FIND "REG_DWORD"') do (
set /a type=%%y
)
goto :EOF
:getstart
for /f "Tokens=2,3" %%x in ('reg query "HKLM"System"CurrentControlSet"Services"!svc!" /V start^|FIND "REG_DWORD"') do (
set /a start=%%y
)
goto :EOF
:subkey
set svc=%~nx1


重启机器


step 2关联的注册表项及重新安装msdtc组件
MSDTC_2.bat
@echo off
setlocal
@echo %WINDIR%"System32"msdtc.exe -uninstall
%WINDIR%"System32"msdtc.exe -uninstall
call :delkey "HKCR"CID"
call :delkey "HKLM"SYSTEM"CurrentControlSet"Services"MSDTC"
call :delkey "HKLM"SYSTEM"ControlSet001"Services"MSDTC"
call :delkey "HKLM"SYSTEM"ControlSet002"Services"MSDTC"
call :delkey "HKLM"Software"Microsoft"MSDTC"
@echo %WINDIR%"System32"msdtc.exe -install
%WINDIR%"System32"msdtc.exe -install
endlocal
goto :EOF
:delkey
set key=%1
call :delkeyq %key% >nul 2>&1
@echo.
goto :EOF
:delkeyq
REG DELETE %key% /F


step 3
MSDTC_3.bat
@echo off
if {%1}=={} @echo Syntax: MSDTC3 Filename&goto :EOF
if not exist %1 Syntax: MSDTC3 Filename - %1 was NOT found.&goto :EOF
setlocal
set filename=%1
for /f "Tokens=*" %%r in ('type %filename%') do (
%%r
)
reg add "HKLM"SOFTWARE"Microsoft"MSDTC"XADLL" /F
regsvr32 mtxoci.dll
endlocal

 

posted @ 2008-08-04 23:05 poplau 阅读(179) | 评论 (0)编辑

从书上看到

ManualWorkflowSchedulerService一般用于ASP.NET写的应用中

先初始化

System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService scheduler = new System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService();
workflowRuntime.AddService(scheduler);

 

在使用中一定要注意红色部分

 WorkflowRuntime workFlowRunTime = Application[ClassPublic.WorkFlowConstValue.WorkflowRuntimeName] as WorkflowRuntime;
        ManualWorkflowSchedulerService Schedul = workFlowRunTime.GetService<ManualWorkflowSchedulerService>();
        WorkflowInstance wInstance = workFlowRunTime.CreateWorkflow(typeof(BillWF.BillWorkFlow));
        modelBillTable.BillId = wInstance.InstanceId;
        wInstance.Start();
        Schedul.RunWorkflow(wInstance.InstanceId);

只有执行了红色部分

工作流才能真正驱动

 

因此在执行状态机跳转的时候,也需要使用红色部分

BillWF.BillService billService = workFlowRunTime.GetService<BillWF.BillService>();
        billService.RaiseEvent("eveUserApply", wInstance.InstanceId);
        Schedul.RunWorkflow(wInstance.InstanceId);

posted @ 2008-07-30 10:24 poplau 阅读(101) | 评论 (0)编辑

今天在使用iis5.1的时候发现

如果使用停止站点服务,再启动站点服务时(点击站点上的按钮),application里面的数据不会消失.

 

只有IIS重新启动的时候application里面的数据才会消失,为此还和一个人争了半天.

 

我没有IIS6,不知道IIS6是什么样的情况.不知道园子里的朋友有没有遇见和我一样的问题,是什么原因?

posted @ 2008-07-21 20:18 poplau 阅读(107) | 评论 (2)编辑

看了网易的一则新闻
北京奥运会中国体育代表团领奖服正式亮相
点进去一看
却有种说不出的难受,不是说款式怎么样
生产服装的厂商不是国产的品牌,而是阿迪,而且服装中没有一个汉字。。。
为什么是这样,为什么不是李宁或者其他的品牌?
我真的觉得遗憾。
PS:我不是什么愤青,我也并不反感阿迪,只是为我们的民族企业感到遗憾
长叹兮~~~~

阿迪达斯

没有一个中文

posted @ 2008-07-16 12:08 poplau 阅读(365) | 评论 (11)编辑

记得以前画漫画,很喜欢日本的北条和中国的颜开。
他们的书几乎每出一集都要排着对去买。有的书还去买两套,一套看,一套保留。
他们的漫画每天一遍又一遍的临摹,然后用从外地邮购的网纹纸上网纹效果,复印,刀刻。
后来自己编故事,自己画着稚嫩的漫画去投稿。
几乎把自己全部的精力和财力都画在了上面。
希望自己有一天也能像着偶像们一样。
后来,却没能再继续。。。(原因1、2、3)
尽管我现在对日本的很多做法很反感,虽然北条的作品后来越来越不怎么样。
可是这么多年以后,我依然在心目中保存下了这两位漫画的偶像。

做程序也是因为喜爱。
可以没日没夜的写代码。
可以不要钱就拼命加班。
可以为一段自以为好玩的小程序感叹好一阵。
可是已经没有
我要做一个像XXX那样的程序员这种冲动和愿景

有时候很困惑,找不到答案
这个XXX到底是谁?
博客园的兄弟姐妹
你们有没有自己的程序员偶像呢?
也许我真的是孤陋寡闻吧

posted @ 2008-07-14 18:10 poplau 阅读(62) | 评论 (2)编辑
感觉自己用EXTJS 1.1和AJAX1.0做网站都快弄烦了。
ExtJs 2.0推出了很久,自己一直都没有化时间去学习,感觉2.0在结构上和1.1有很大的不同。而且看了一下阿2.0的JS要500K,再加上偶基本只用到BasicDialog和TextField以及MessageBox(编译后只有204K),只有先暂时不研究2.0了。因为偶觉得1.1和.net ajax1.0结合的还不错。有很多控件的功能可以自己用JS实现。

做了快1年的网站,从PS开始,到CSS+DIV,到DHTML,到EXTJS,到AJAX,到.NET,几乎全部都在做,开始还很有兴趣,可是到后来自己熟练了,写这些变成了一种程式化,标准化,一样的模式,一样的操作。都做着重复的事情。自己也没有机会亲临更大型的网站,也没有人与之交流。确实很烦恼。

前段时间看了下《程序员》上那篇忽悠(他人评价)文章《写给WEB2.0站长,不仅仅是泼冷水》,更是一头雾水。

一个做网站的程序员,需要怎样的提升才能做更大型的网站?用ASP.NET。呵呵
posted @ 2008-07-09 18:18 poplau 阅读(77) | 评论 (3)编辑

以往的概念很混淆。
今天看了那张图,终于明白了一些参数通信的道理。。。很初级的

这张图说明了工作流如何与宿主程序进行通信。开始我一直把这个接口类当成工作流的一部分,实在是走了很多弯路。
我写了一个小程序,首先把用户名在工作流创建初期放到工作流内部去。
然后,再把这个用户名从工作流里面读取出来。

程序在这里,我还是习惯写WEB方式的,需要安装AJAX1.0
BillDayTwo.rar

posted @ 2008-07-08 17:31 poplau 阅读(121) | 评论 (0)编辑
如果在Workflow中定义了一个属性,如何才能在工作流创建后对这个属性进行修改呢?
今天折腾了一天,也不见有什么效果,只搞懂了一半,先写出来,没有领悟到的等以后想通了再写。
在创建工作流的时候,可以用CreateWorkflow(typeof(wf),Dictionary<string,object>)这样的方式将参数值传入工作流。但是如果工作流已经创建,宿主程序又如何把值传入工作流呢?
需要用到ExternalDataEventArgs这个东东,需要自己继承一个这样的类
[Serializable]
    
public class BillExternalDataEventArgs : ExternalDataEventArgs {
        
private Decimal _mycash;
        
public Decimal Cash {
            
get return _mycash; }
            
set { _mycash = value; }
        }

        
public BillExternalDataEventArgs(Guid instanceId,Decimal decCash) : base(instanceId) {
            _mycash 
= decCash;
        }

    }
然后在把对应的接口进行相应的调整
    [ExternalDataExchange]
    
public interface IBillWorkFlow
    
{
        Decimal GetCash(Decimal decCash);
        
event EventHandler<BillExternalDataEventArgs> BillSubmit;
        
event EventHandler<BillExternalDataEventArgs> BillOk;
    }

[Serializable]
    
public class MyBillWorkFlow : IBillWorkFlow {
        
public MyBillWorkFlow() {
            System.Diagnostics.Debug.WriteLine(
"MyBillWorkFlow Init");
        }


        Dictionary
<string, EventHandler<BillExternalDataEventArgs>> _EventList = new Dictionary<string, EventHandler<BillExternalDataEventArgs>>();

        
public void RaisEvent(string strName,Guid guidInstanceId,Decimal decCash) {
            
if (_EventList[strName] != null)
            
{
                
try
                
{
                    EventHandler
<BillExternalDataEventArgs> evehandler = _EventList[strName];
                    BillExternalDataEventArgs ede 
= new BillExternalDataEventArgs(guidInstanceId,decCash);
                    evehandler(
this, ede);
                }

                
catch 
                
                }

            }

        }


        
public Decimal GetCash(Decimal decCash)
        

            
return decCash;
        }


        
public event EventHandler<BillExternalDataEventArgs> BillSubmit
        
{
            add 
{
                System.Diagnostics.Debug.WriteLine(
"add BillSubmit event");
                _EventList.Add(
"BillSubmit", value); 
            }

            remove 
{ _EventList.Remove("BillSubmit"); }
        }


        
public event EventHandler<BillExternalDataEventArgs> BillOk
        
{
            add 
{ _EventList.Add("BillOk", value); }
            remove 
{ _EventList.Remove("BillOk"); }
        }

    }

然后在工作流中定义
public Billdayone.BillExternalDataEventArgs _cash = default(Billdayone.BillExternalDataEventArgs);

这个_cash就是宿主与工作流之间传递的重要属性。

只需要调用
RaisEvent(string strName,Guid guidInstanceId,Decimal decCash)//Decimal decCash就是宿主向工作流传递的参数,将传递给_cash.Cash
这样就完成了宿主向工作流传递参数。

但是我还没有弄明白怎么能够得到工作流中的属性值。还在学习中。。。还不知道怎么办?。。。
posted @ 2008-07-07 22:40 poplau 阅读(82) | 评论 (0)编辑
     摘要: 今天做WF 的.NET编程一直弄了好久,对状态机方式今天终于有了一点小小的入门。还要感谢曲滨的程序asp.net使用wwf1,配置 web.config在 <configuration> 与<system.web>之间需要添加[代码]好了,只能做到这里,关于如何传参数以及把工作流从内存中保存下来要进一步学些。。。 downloadBilldayone.rar开发环境 .ne... 阅读全文
posted @ 2008-07-06 21:45 poplau 阅读(225) | 评论 (0)编辑

摘要:

为什么要使用序列化?

最重要的两个原因是:

1.      将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;

2.      按值将对象从一个应用程序域发送至另一个应用程序域。

例如,序列化可用于在 ASP.NET 中保存会话状态,以及将对象复制到 Windows 窗体的剪贴板中。

它还可用于按值将对象从一个应用程序域远程传递至另一个应用程序域。

本文简要介绍了 Microsoft .NET 中使用的序列化。

一、        简介

 

序列化是指将对象实例的状态存储到存储媒体的过程。

在此过程中,

1.      先将对象的公共字段和私有字段以及类的名称(包括类所在的程序集)转换为字节流,

2.      然后再把字节流写入数据流。

3.      在随后对对象进行反序列化时,将创建出与原对象完全相同的副本。

在面向对象的环境中实现序列化机制时,必须在易用性和灵活性之间进行一些权衡。

只要您对此过程有足够的控制能力,就可以使该过程在很大程度上自动进行。例如,简单的二进制序列化不能满足需要,或者,由于特定原因需要确定类中那些字段需要序列化。

以下各部分将探讨 .NET 框架提供的可靠的序列化机制,并着重介绍使您可以根据需要自定义序列化过程的一些重要功能。

二、         持久存储

我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。

尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,并且在需要跟踪对象的层次结构时,会变得越来越复杂。

可以想象一下编写包含大量对象的大型业务应用程序的情形,程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。

序列化提供了轻松实现这个目标的快捷方法。

公共语言运行时 (CLR) 管理对象在内存中的分布,.NET 框架则通过使用反射提供自动的序列化机制。

对象序列化后,类的名称、程序集以及类实例的所有数据成员均被写入存储媒体[本文中的存储媒体是什么?xml]中。

对象通常用成员变量来存储对其他实例的引用。类序列化后,序列化引擎将跟踪所有已序列化的引用对象,以确保同一对象不被序列化多次[序列化是针对对象的?那岂不是一个程序会需要很多的序列化?]

.NET 框架所提供的序列化体系结构可以自动正确处理对象图表和循环引用。

对对象图表[什么是对象图表?]的唯一要求是,由正在进行序列化的对象所引用的所有对象都必须标记为 Serializable(请参阅基本序列化)。否则,当序列化程序试图序列化未标记的对象时将会出现异常。

当反序列化已序列化的类时,将重新创建该类,并自动还原所有数据成员的值。

三、        按值封送

对象仅在创建对象的应用程序域中有效。除非对象是从 MarshalByRefObject 派生得到或标记为 Serializable,否则,任何将对象作为参数传递或将其作为结果返回的尝试都将失败。

如果对象标记为 Serializable[如何标记为Serializable],则该对象将被自动序列化,并从一个应用程序域传输至另一个应用程序域,然后进行反序列化,从而在第二个应用程序域中产生出该对象的一个精确副本。此过程通常称按值封送

如果对象是从 MarshalByRefObject 派生得到,则从一个应用程序域传递至另一个应用程序域的是对象引用,而不是对象本身。

也可以将从 MarshalByRefObject 派生得到的对象标记为 Serializable

远程使用此对象时,负责进行序列化并已预先配置为 SurrogateSelector 的格式化程序将控制序列化过程,并用一个代理替换所有从 MarshalByRefObject 派生得到的对象。如果没有预先配置为 SurrogateSelector,序列化体系结构将遵从下面的标准序列化规则(请参阅序列化过程的步骤)。

四、        基本序列化

要使一个类可序列化,最简单的方法是使用 Serializable 属性[为什么webservice中没有标记Serializable]

对它进行标记,如下所示:

[Serializable]

 public class MyObject {

  public int n1 = 0;

  public int n2 = 0;

  public String str = null;

}

以下代码片段说明了如何将此类的一个实例序列化为一个文件[我们不需要用手写这些代码吧?]

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();

本例使用二进制格式化程序进行序列化。

您只需创建一个要使用的流和格式化程序的实例,然后调用格式化程序的 Serialize 方法。流和要序列化的对象实例作为参数提供给此调用。

类中的所有成员变量(甚至标记为 private 的变量)都将被序列化,但这一点在本例中未明确体现出来。

在这一点上,二进制序列化不同于只序列化公共字段的 XML 序列化程序[共有多少种序列化?二进制序列化和xml序列化分别用在什么地方?二进制/XML是不是就是本文所说的存储媒体?]

将对象还原到它以前的状态也非常容易。

首先,创建格式化程序和流以进行读取,

然后让格式化程序对对象进行反序列化。

以下代码片段说明了如何进行此操作。

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);

上面所使用的 BinaryFormatter 效率很高,能生成非常紧凑的字节流。

所有使用此格式化程序序列化的对象也可使用它进行反序列化,对于序列化将在 .NET 平台上进行反序列化的对象,此格式化程序无疑是一个理想工具。

需要注意的是,对对象进行反序列化时并不调用构造函数[不调用构造函数,会不会为编程带来影响,例如不能在构造函数中添加逻辑?还是,不需要关心构造函数,因为对象的变量足以表明对象的状态?]。对反序列化添加这项约束,是出于性能方面的考虑[不调用构造函数?者对性能会有多大影响,这么说调用构造函数并不是完全没有必要?]。但是,这违反了对象编写者通常采用的一些运行时约定,因此,开发人员在将对象标记为可序列化时,应确保考虑了这一特殊约定。

如果要求具有可移植性,请使用 SoapFormatter。所要做的更改只是将以上代码中的格式化程序换成 SoapFormatter,而 Serialize Deserialize 调用不变。

对于上面使用的示例,该格式化程序将生成以下结果。

<SOAP-ENV:Envelope

  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">

 

  <SOAP-ENV:Body>

    <a1:MyObject id="ref-1">

      <n1>1</n1>

      <n2>24</n2>

      <str id="ref-3">一些字符串</str>

    </a1:MyObject>

  </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

需要注意的是,无法继承 Serializable 属性。如果从 MyObject 派生出一个新的类,则这个新的类也必须使用该属性进行标记,否则将无法序列化。[如果Serializable 属性不能继承,为什么webservice类中没有设置Serializable 属性?]

例如,如果试图序列化以下类实例,将会显示一个 SerializationException,说明 MyStuff 类型未标记为可序列化。

public class MyStuff : MyObject

{

  public int n3;

}

使用序列化属性非常方便,但是它存在上述的一些限制。

有关何时标记类以进行序列化(因为类编译后就无法再序列化),请参考有关说明(请参阅下面的序列化规则)。

五、        选择性序列化

类通常包含不应被序列化的字段。例如,假设某个类用一个成员变量来存储线程 ID。当此类被反序列化时,序列化此类时所存储的 ID 对应的线程可能不再运行,所以对这个值进行序列化没有意义。

可以通过使用 NonSerialized 属性标记成员变量来防止它们被序列化,如下所示:

[Serializable]

public class MyObject

{

  public int n1;

  [NonSerialized] public int n2;

  public String str;

}

六、        自定义序列化

可以通过在对象上实现 ISerializable 接口来自定义序列化过程[自定义序列化过程是什么,自己写代码序列化,反序列化对象?]

这一功能在反序列化后成员变量的值失效时尤其有用,但是需要为变量提供值以重建对象的完整状态。

要实现 ISerializable,需要实现 GetObjectData 方法以及一个特殊的构造函数[不是反序列化的时候,不调用构造函数吗?],在反序列化对象时要用到此构造函数。

以下代码示例说明了如何在前一部分中提到的 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,编译器将发出警告。但是,由于无法强制实现构造函数,所以,缺少构造函数时不会发出警告。如果在没有构造函数的情况下尝试反序列化某个类,将会出现异常。

在消除潜在安全性和版本控制问题等方面,当前设计优于 SetObjectData 方法。例如,如果将 SetObjectData 方法定义为某个接口的一部分,则此方法必须是公共方法,这使得用户不得不编写代码来防止多次调用 SetObjectData 方法。可以想象,如果某个对象正在执行某些操作,而某个恶意应用程序却调用此对象的 SetObjectData 方法,将会引起一些潜在的麻烦。

在反序列化过程中,使用出于此目的而提供的构造函数将 SerializationInfo 传递给类。对象反序列化时,对构造函数的任何可见性约束都将被忽略,因此,可以将类标记为 publicprotectedinternal 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);

  }

}

切记要在反序列化构造函数中调用基类,否则,将永远不会调用基类上的构造函数,并且在反序列化后也无法构建完整的对象。

对象被彻底重新构建,但是在反序列化过程中调用方法可能会带来不良的副作用,因为被调用的方法可能引用了在调用时尚未反序列化的对象引用[不明白什么意思?是当前对象,还是其它对象?]

如果正在进行反序列化的类实现了 DeserializationCallback,则反序列化整个对象图表后,将自动调用 OnSerialization 方法。此时,引用的所有子对象均已完全还原。

有些类不使用上述事件侦听器,很难对它们进行反序列化,散列表[什么是散列表?]便是一个典型的例子。

在反序列化过程中检索关键字/值对非常容易,但是,由于无法保证从散列表派生出的类已反序列化,所以把这些对象添加回散列表时会出现一些问题。因此,建议目前不要在散列表上调用方法。

七、        序列化过程的步骤

在格式化程序上调用 Serialize 方法时,对象序列化按照以下规则进行:

  • 检查格式化程序是否有代理选取器[是不是序列化的对象中所引用的对象都必须是可序列化的对象,否则无法反序列化。那么,是不是webservice不能引用未序列化的对象?]。如果有,检查代理选取器是否处理指定类型的对象。如果选取器处理此对象类型,将在代理选取器上调用 ISerializable.GetObjectData
  • 如果没有代理选取器或有却不处理此类型,将检查是否使用 Serializable 属性对对象进行标记。如果未标记,将会引发 SerializationException
  • 如果对象已被正确标记,将检查对象是否实现了 ISerializable。如果已实现,将在对象上调用 GetObjectData
  • 如果对象未实现 Serializable,将使用默认的序列化策略,对所有未标记为 NonSerialized 的字段都进行序列化。

八、        版本控制

.NET 框架支持版本控制和并排执行,并且,如果类的接口保持一致,所有类均可跨版本工作。

由于序列化涉及的是成员变量而非接口,所以,在向要跨版本序列化的类中添加成员变量,或从中删除变量时,应谨慎行事。特别是对于未实现 ISerializable 的类更应如此。

若当前版本的状态发生了任何变化(例如添加成员变量、更改变量类型或更改变量名称),都意味着如果同一类型的现有对象是使用早期版本进行序列化的,则无法成功对它们进行反序列化。

如果对象的状态需要在不同版本间发生改变,类的作者可以有两种选择:

  • 实现 ISerializable。这使您可以精确地控制序列化和反序列化过程,在反序列化过程中正确地添加和解释未来状态。
  • 使用 NonSerialized 属性标记不重要的成员变量。仅当预计类在不同版本间的变化较小时,才可使用这个选项。例如,把一个新变量添加至类的较高版本后,可以将该变量标记为 NonSerialized,以确保该类与早期版本保持兼容[序列化对象中含有NonSerialized标记,是不是有隐患?]

九、        序列化规则

由于类编译后便无法序列化[序列化的时机是什么时候,由谁(CLR还是其它)来实现序列化?凡序列化的时机是什么时候,由谁来实现?那么,webservice是什么时候序列化,什么时候反序列化?][类编译后便无法再序列化?是不是类和对象都可以序列化?][序列化是不是和原数据表单联系很密切?],所以在设计新类时应考虑序列化。

需要考虑的问题有:

1.      是否必须跨应用程序域来发送此类?

2.      是否要远程使用此类?

3.      用户将如何使用此类?

也许他们会从我的类中派生出一个需要序列化的新类。只要有这种可能性,就应将类标记为可序列化。除下列情况以外,最好将所有类都标记为可序列化:

  • 所有的类都永远也不会跨越应用程序域。如果某个类不要求序列化但需要跨越应用程序域,请从 MarshalByRefObject 派生此类。
  • 类存储仅适用于其当前实例的特殊指针。例如,如果某个类包含非受控的内存或文件句柄,请确保将这些字段标记为 NonSerialized 或根本不序列化此类。
  • 某些数据成员包含敏感信息。在这种情况下,建议实现 ISerializable 并仅序列化所要求的字段。

我的问题:

1本文中的存储媒体是什么?xml

2:序列化是针对对象的?那岂不是一个程序会需要很多的序列化?

3:什么是对象图表?

4如何标记为Serializable?在类中,标记Serializable特性?

5:为什么webservice类中没有标记Serializable

6:一般情况下,我们不需要用手写这些序列化,反序列化代码吧?

7:共有多少种序列化?二进制序列化和xml序列化分别用在什么地方?二进制/XML是不是就是本文所说的存储媒体?

8:不调用构造函数,会不会为编程带来影响,例如不能在构造函数中添加逻辑?还是,不需要关心构造函数,因为对象的变量足以表明对象的状态?

9:反序列化不调用构造函数?者对性能会有多大影响,这么说调用构造函数并不是完全没有必要?

10:如果Serializable 属性不能继承,为什么webservice类中没有设置Serializable 属性?

11:自定义序列化过程是什么,自己写代码序列化,反序列化对象?

12:反序列化的时候,不能调用构造函数吗?

13对象被彻底重新构建,但是在反序列化过程中调用方法可能会带来不良的副作用,因为被调用的方法可能引用了在调用时尚未反序列化的对象引用[不明白什么意思?是当前对象,还是其它对象?]

14:什么是散列表?

15:是不是序列化的对象中所引用的对象都必须是可序列化的对象,否则无法反序列化。那么,是不是webservice不能引用未序列化的对象?

16:序列化对象中含有NonSerialized标记,是不是有隐患?

17序列化的时机是什么时候,由谁(CLR还是其它)来实现序列化?凡序列化的时机是什么时候,由谁来实现?那么,webservice是什么时候序列化,什么时候反序列化?

18:类编译后便无法再序列化?是不是类和对象都可以序列化?

19:序列化是不是和原数据表单联系很密切?

posted @ 2008-07-04 14:52 poplau 阅读(24) | 评论 (0)编辑
<2008年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

与我联系

搜索

 

常用链接

留言簿

我参加的小组

我的标签

随笔分类

随笔档案

最新评论

  • 1. re: application和站点停止
  • @斧头帮少帮主
    恩,可能是这样的,因此,使用IISRESET命令或者更改WEBCONFIG文件是最好的,可以把APPLICATION里面的数据清空
  • --poplau
  • 2. re: application和站点停止
  • 不太确定的说,停止后得等一会才能把缓存和正在执行的线程停止.好些不是立即回收.
  • --斧头帮少帮主
  • 3. re: 遗憾
  • 你要是看过颁奖礼仪的服装,就会感觉这个其实还算不错
  • --丁学
  • 4. re: 遗憾
  • 看看这里,一切都会明白:



  • --要有好的心情
  • 5. re: 遗憾
  • 我是愤青,我很愤怒!!!!
  • --鬼不灵

阅读排行榜

评论排行榜