100165476.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 201 行 · 第 1/3 页
HTM
201 行
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Hello obj = (Hello)Activator.GetObject(typeof(Hello),</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> "tcp://localhost:8086/Hi");</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (obj == null)</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("could not locate server");</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> return;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> MySerialized ser = obj.GetMySerialized();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (!RemotingServices.IsTransparentProxy(ser))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("ser is not a transparent proxy");</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> ser.Foo();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> MyRemote rem = obj.GetMyRemote();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (RemotingServices.IsTransparentProxy(rem))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Console.WriteLine("rem is a transparent proxy");</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> rem.Foo();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在客户控制台窗口中,可以看到在客户机上调用了</span><span lang="EN-US">ser</span><span style="FONT-FAMILY: 宋体">对象,如图</span><span lang="EN-US">16-8</span><span style="FONT-FAMILY: 宋体">所示。因为对象</span><span lang="EN-US">ser</span><span style="FONT-FAMILY: 宋体">与客户机是串行化的,所以它不是透明代理对象。与</span><span lang="EN-US">ser</span><span style="FONT-FAMILY: 宋体">对象相反,客户机上的</span><span lang="EN-US">rem</span><span style="FONT-FAMILY: 宋体">对象是透明代理对象。在</span><span lang="EN-US">rem</span><span style="FONT-FAMILY: 宋体">对象上调用的方法被传递给服务器。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">在服务器的输出结果中,可以看到调用了远程对象</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt">MyRemote</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">的</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt">Foo()</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">方法,如图</span><span lang="EN-US" style="LETTER-SPACING: 0.1pt">16-9</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: 0.1pt">所示。</span></p>
<p align="center"><span lang="EN-US"><img height="81" src="16/image008.jpg" width="226" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black"> 16-8</span></p>
<p align="center"><span lang="EN-US"><img height="136" src="16/image009.jpg" width="213" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black"> 16-9</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">1. </span><span style="FONT-FAMILY: 黑体">安全性和串行化的对象</span></h4>
<p class="MsoNormal"><span lang="EN-US">.NET Remoting</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">ASP.NET Web</span><span style="FONT-FAMILY: 宋体">服务的一个重要区别是对象编组的方式。在</span><span lang="EN-US">ASP.NET Web</span><span style="FONT-FAMILY: 宋体">服务中,只有公共字段和属性是通过网络传送的。而</span><span lang="EN-US">.NET Remoting</span><span style="FONT-FAMILY: 宋体">使用另一种串行化机制来串行化所有的数据,包括所有的私有数据。不怀好意的客户可以在串行化和并行化过程中破坏应用程序。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">为了解决这个问题,</span><span lang="EN-US">.NET 1.1</span><span style="FONT-FAMILY: 宋体">改变了通过</span><span lang="EN-US">.NET Remoting</span><span style="FONT-FAMILY: 宋体">边界传送对象的方式,定义了两个自动并行化级别:低级并行化和完整并行化。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在默认情况下,使用低级并行化。在低级并行化中,不能传送</span><span lang="EN-US">ObjRef</span><span style="FONT-FAMILY: 宋体">对象,以及实现</span><span lang="EN-US">ISponsor</span><span style="FONT-FAMILY: 宋体">接口的对象。为了传送这两类对象,可以把并行化级别改为完整级别。这可以通过编程来实现:即创建一个格式化接收器提供程序,并给它赋予属性</span><span lang="EN-US">TypeFilterLevel</span><span style="FONT-FAMILY: 宋体">。对于二进制格式标识符,提供程序类是</span><span lang="EN-US">BinaryServerFormatterSinkProvider</span><span style="FONT-FAMILY: 宋体">,对于</span><span lang="EN-US">SOAP</span><span style="FONT-FAMILY: 宋体">格式标识符,提供程序类是</span><span lang="EN-US">SoapServerFormatterSinkProvider</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">下面的代码说明了如何利用完整级别的串行化支持创建一个</span><span lang="EN-US">TCP</span><span style="FONT-FAMILY: 宋体">信道:</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">BinaryServerFormatterSinkProvider serverProvider =</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> new BinaryServerFormatterSinkProvider();</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">serverProvider. TypeFilterLevel = TypeFilterLevel.Full;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">BinaryClientFormatterSinkProvider clientProvider =</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">new BinaryClientFormatterSinkProvider();</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">IDictionary props = new Hashtable()’</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">Props["port"] = 6789;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">TcpChannel channel = new TcpChannel(props, clientProvider, serverProvider);</span></p>
<p class="MsoNormal" style="FTEL: 21.2pt"><span style="FONT-FAMILY: 宋体">首先,创建一个</span><span lang="EN-US">BinaryServerFormatterSinkProvider</span><span style="FONT-FAMILY: 宋体">,并把</span><span lang="EN-US">TypeFilterLevel</span><span style="FONT-FAMILY: 宋体">属性设置为</span><span lang="EN-US">TypeFilterLevel.Full</span><span style="FONT-FAMILY: 宋体">。枚举</span><span lang="EN-US">TypeFilterLevel</span><span style="FONT-FAMILY: 宋体">是在命名空间</span><span lang="EN-US">System.Runtime.Serialization.Formatters</span><span style="FONT-FAMILY: 宋体">中定义的,所以必须声明这个命名空间。对于信道的客户端,创建一个</span><span lang="EN-US">BinaryClientFormatter SinkProvider</span><span style="FONT-FAMILY: 宋体">。客户端和服务器端的格式化接收器提供程序实例都传送给</span><span lang="EN-US">TcpChannel</span><span style="FONT-FAMILY: 宋体">的构造函数,定义信道特性的</span><span lang="EN-US">IDictionary</span><span style="FONT-FAMILY: 宋体">属性也被传送给该构造函数。</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">2. </span><span style="FONT-FAMILY: 黑体">定向特性</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">远程对象从来都不通过线路传输,但是,值类型和可串行化的类是通过线路传输的。有时只需要在一个方向上发送数据。这在数据通过网络传输时尤其重要。例如,如果要把集合中的数据发送给服务器,服务器再对这些数据执行一些计算操作,并给客户机返回一个简单的值,把集合发送回客户机就不是很有效。如果数据应发送给服务器、客户机或双向发送,则可以使用</span><span lang="EN-US">COM</span><span style="FONT-FAMILY: 宋体">给参数声明定向特性</span><span lang="EN-US">[in]</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">[out]</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US"> [in, out]</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">在</span><span lang="EN-US" style="COLOR: black">C#</span><span style="COLOR: black; FONT-FAMILY: 宋体">中,有相似的</span><span style="FONT-FAMILY: 宋体">特<span style="COLOR: black">性:即</span></span><span lang="EN-US" style="COLOR: black">ref</span><span style="COLOR: black; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="COLOR: black">out</span><span style="COLOR: black; FONT-FAMILY: 宋体">型方法参数。</span><span lang="EN-US" style="COLOR: black">ref</span><span style="COLOR: black; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="COLOR: black">out</span><span style="COLOR: black; FONT-FAMILY: 宋体">型方法参数可以用在可串行化的值类型和引用类型上。使用</span><span lang="EN-US" style="COLOR: black">ref</span><span style="COLOR: black; FONT-FAMILY: 宋体">参数时,数据可以双向编组;使用</span><span lang="EN-US" style="COLOR: black">out</span><span style="COLOR: black; FONT-FAMILY: 宋体">时,数据是从服务器发送到客户机;不使用参数</span><span lang="EN-US" style="COLOR: black">ref</span><span style="COLOR: black; FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="COLOR: black">out</span><span style="COLOR: black; FONT-FAMILY: 宋体">时,数据是从客户机发送到服务器。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="FTEL: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">有关</span><span lang="EN-US">ref</span><span style="FONT-FAMILY: 楷体_GB2312">和</span><span lang="EN-US">out</span><span style="FONT-FAMILY: 楷体_GB2312">关键字的内容详见第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 楷体_GB2312">章。</span></p></div>
<!-- page -->
<div class="page" style="text-align: center">
<a href="100165475.htm">上一页</a> <a href="index.html">首页</a> <a href="100165477.htm">下一页</a>
</div>
<div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
<div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
图书导读
</div>
<div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
<!--导读-->
<h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100165476.htm'><font color='red'>16.5.6 在远程方法中传递对象</font></a></h1>
<div id="divRealteNod2" style="padding-left: 2px">
<div style='float:left;width:49%'>·<a href='100165473.htm'>16.5.3 ChannelServices和RemotingConfiguration</a></div><div style='float:right;width:49%'>·<a href='100165474.htm'>16.5.4 对象的激活</a></div><div style='float:left;width:49%'>·<a href='100165475.htm'>16.5.5 消息接收器</a></div><div style='float:right;width:49%'>·<a href='100165477.htm'>16.5.7 生存期管理</a></div><div style='float:left;width:49%'>·<a href='100165478.htm'>16.6 .NET Remoting的其他特性</a></div><div style='float:right;width:49%'>·<a href='100165479.htm'>16.6.1 配置文件(1)</a></div></div>
</div>
</div>
</div>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?