100165474.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 139 行 · 第 1/2 页

HTM
139
字号
<p class="a6" style="MARGIN-TOP: 8.15pt; BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US" style="COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello obj = (Hello)RemotingServices.Connect(typeof(Hello), </span></p>
<p class="a6" style="MARGIN-TOP: 0cm; BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US" style="COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;tcp://localhost:8086/Hi&quot;);</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">如果要使用简单的运算符</span><span lang="EN-US" style="COLOR: black">new</span><span style="COLOR: black; FONT-FAMILY: 宋体">去激活知名的远程对象,则必须在客户机上使用</span><span lang="EN-US" style="COLOR: black">RemotingConfiguration.RegisterWellKnownClientType()</span><span style="COLOR: black; FONT-FAMILY: 宋体">注册远程对象。这里需要的参数与上面的相似:即都需要远程对象的类型和</span><span lang="EN-US" style="COLOR: black">URI</span><span style="COLOR: black; FONT-FAMILY: 宋体">。运算符</span><span lang="EN-US" style="COLOR: black">new</span><span style="COLOR: black; FONT-FAMILY: 宋体">实际上并没有创建新的远程对象,而是返回一个与</span><span lang="EN-US" style="COLOR: black">Activator.GetObject()</span><span style="COLOR: black; FONT-FAMILY: 宋体">相似的代理对象。如果使用</span><span lang="EN-US" style="COLOR: black">WellKnownObjectMode.SingleCall</span><span style="COLOR: black; FONT-FAMILY: 宋体">标记注册远程对象,规则总是一样的:即使用每一个方法调用创建远程对象。</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US" style="COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RemotingConfiguration.RegisterWellKnownClientType(typeof(Hello),</span></p>
<p class="a6" style="BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US" style="COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;tcp://localhost:8086/Hi&quot;);</span></p>
<p class="a6" style="MARGIN-TOP: 0cm; BACKGROUND: #f2f2f2; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US" style="COLOR: black">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello obj = new Hello();</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">3. </span><span style="FONT-FAMILY: 黑体">激活</span><span lang="EN-US">Client-Activated</span><span style="FONT-FAMILY: 黑体">对象</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">远程对象可以为客户保存状态。</span><span lang="EN-US">Activator.CreateInstance()</span><span style="FONT-FAMILY: 宋体">用于创建客户激活的远程对象。使用</span><span lang="EN-US">Activator.GetObject()</span><span style="FONT-FAMILY: 宋体">方法,可以在方法调用时创建远程对象,而当方法执行完时,可以删除远程对象。对象不在服务器上保存状态,这一点与</span><span lang="EN-US">Activator.CreateInstance()</span><span style="FONT-FAMILY: 宋体">不同。使用静态的</span><span lang="EN-US">CreateInstance()</span><span style="FONT-FAMILY: 宋体">方法,按次序开始激活,进而创建远程对象。在租约时间到期并且垃圾收集发挥作用之前,对象将一直处于激活状态。本章后面的内容中将讨论租约机制。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">一些重载的</span><span lang="EN-US">Activator.CreateInstance()</span><span style="FONT-FAMILY: 宋体">方法只能用于创建本地对象。为了创建远程的对象,就需要一个能够传送激活属性的方法。我们的示例中就使用了一个重载的方法,该方法接收两个字符串参数,第一个参数是程序集的名称,第二个参数是类型,第三个参数是对象数组。在</span><span lang="EN-US">UrlAttribute</span><span style="FONT-FAMILY: 宋体">的帮助下,可以在对象数组中指定信道和对象的名称。为了使用</span><span lang="EN-US">UrlAttribute</span><span style="FONT-FAMILY: 宋体">类,必须指定命名空间</span><span lang="EN-US">System.Runtime.Remoting.Activation</span><span style="FONT-FAMILY: 宋体">:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">object[] attrs = {new UrlAttribute(&quot;tcp://localhost:8086/Hello&quot;) };</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">ObjectHandle handle = Activator.CreateInstance(</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;RemoteHello&quot;, &quot;Wrox.ProCSharp.Remoting.Hello&quot;, attrs);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">if (handle == null)</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">&nbsp;&nbsp; Console.WriteLine(&quot;could not locate server&quot;);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp; return;</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">Hello obj = (Hello)handle.Unwrap();</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">Console.WriteLine(obj.Greeting(&quot;Christian&quot;));</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">当然,对于客户激活的对象而言,也可以使用运算符</span><span lang="EN-US" style="COLOR: black">new</span><span style="COLOR: black; FONT-FAMILY: 宋体">替代</span><span lang="EN-US" style="COLOR: black">Activator</span><span style="COLOR: black; FONT-FAMILY: 宋体">类。如果使用运算符</span><span lang="EN-US" style="COLOR: black">new</span><span style="COLOR: black; FONT-FAMILY: 宋体">,就必须使用</span><span lang="EN-US" style="COLOR: black">RemotingConfiguration.RegisterActivatedClientType()</span><span style="COLOR: black; FONT-FAMILY: 宋体">注册客户激活的对象。在客户激活的对象体系中,运算符</span><span lang="EN-US" style="COLOR: black">new</span><span style="COLOR: black; FONT-FAMILY: 宋体">不但返回代理对象,也创建远程对象:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">RemotingConfiguration.RegisterActivatedClientType(typeof(Hello),</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;tcp://localhost:8086/HelloServer&quot;);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">Hello obj = new Hello();</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">4. </span><span style="FONT-FAMILY: 黑体">代理对象</span></h4>
<p class="MsoNormal"><span lang="EN-US">Activator.GetObject() </span><span style="FONT-FAMILY: 宋体">方法和</span><span lang="EN-US">Activator.CreateInstance()</span><span style="FONT-FAMILY: 宋体">方法都给客户返回一个代理对象。实际上得到两个代理对象:即透明代理对象和真实代理对象。透明代理对象看起来像远程对象,它执行远程对象的所有公共方法,这些方法调用真实代理对象的</span><span lang="EN-US">Invoke()</span><span style="FONT-FAMILY: 宋体">方法,传送包含方法调用的消息。在消息接收器的帮助下,</span><span lang="EN-US">RealProxy</span><span style="FONT-FAMILY: 宋体">把消息发送到信道中。</span></p>
<p class="MsoNormal"><span style="COLOR: black; FONT-FAMILY: 宋体">使用</span><span lang="EN-US" style="COLOR: black">RemotingServices.IsTransparentProxy()</span><span style="COLOR: black; FONT-FAMILY: 宋体">方法,可以检查对象是否真是透明代理对象。还可以通过</span><span lang="EN-US" style="COLOR: black">RemotingServices.GetRealProxy()</span><span style="COLOR: black; FONT-FAMILY: 宋体">获取真实代理对象。使用</span><span lang="EN-US" style="COLOR: black">Vasula Studio.NET</span><span style="COLOR: black; FONT-FAMILY: 宋体">调试器,很容易得到真实代理对象的所有属性:</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">ChannelServices.RegisterChannel(new TCPChannel());</span></p>
<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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;tcp://localhost:8086/Hi&quot;);</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">&nbsp;&nbsp; Console.WriteLine(&quot;could not locate server&quot;);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; 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">if (RemotingServices.IsTransparentProxy(obj))</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">&nbsp;&nbsp; Console.WriteLine(&quot;Using a transparent proxy&quot;);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; RealProxy proxy = RemotingServices.GetRealProxy(obj);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">&nbsp; // proxy.Invoke(message);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 18pt"><span style="COLOR: black; FONT-FAMILY: 宋体">下面介绍代理对象的&ldquo;可插入性&rdquo;。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 18pt"><span style="FONT-FAMILY: 宋体">真实代理对象可以用定制的代理对象替代。定制的代理对象可以扩展基类</span><span lang="EN-US">System.Runtime. Remoting.RealProxy</span><span style="FONT-FAMILY: 宋体">。在定制代理对象的构造函数中接收远程对象的类型。调用</span><span lang="EN-US">RealProxy</span><span style="FONT-FAMILY: 宋体">的构造函数,可以创建真实代理对象和透明的代理对象。在构造函数中,在</span><span lang="EN-US">ChannelServices</span><span style="FONT-FAMILY: 宋体">类的帮助下创建消息接收器</span><span lang="EN-US">IChannelSender.CreateMessageSink()</span><span style="FONT-FAMILY: 宋体">,可以实现对已注册信道的访问。除了执行构造函数之外,定制的信道还必须重写</span><span lang="EN-US">Invoke()</span><span style="FONT-FAMILY: 宋体">方法。在</span><span lang="EN-US">Invoke()</span><span style="FONT-FAMILY: 宋体">中,可以对接收到的消息进行分析,然后把它们发送到消息接收器中。</span></p>
<h4 style="FTEL: 21.45pt"><span lang="EN-US">5. </span><span style="FONT-FAMILY: 黑体">消息</span></h4>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">代理对象可以把消息发送到信道中。在服务器端分析了消息之后,方法调用就算完成了,因此,下面讨论消息。</span></p>
<p class="MsoNormal"><span lang="EN-US">.NET Framework</span><span style="FONT-FAMILY: 宋体">有一些消息类可以用于方法调用、响应以及返回消息等。所有的消息类都可以实现接口</span><span lang="EN-US">IMessage</span><span style="FONT-FAMILY: 宋体">,该接口只有一个属性</span><span lang="EN-US">Properties</span><span style="FONT-FAMILY: 宋体">。</span><span lang="EN-US">Properties</span><span style="FONT-FAMILY: 宋体">属性表示一个带有</span><span lang="EN-US">IDictionary</span><span style="FONT-FAMILY: 宋体">接口的字典,字典中包括对象的</span><span lang="EN-US">URI</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">MethodName</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">MethodSignature</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">TypeName</span><span style="FONT-FAMILY: 宋体">、</span><span lang="EN-US">Args</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">CallContext</span><span style="FONT-FAMILY: 宋体">等。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US">16-7</span><span style="FONT-FAMILY: 宋体">是消息类和接口的层次。发送给真实代理对象的消息是</span><span lang="EN-US">MethodCall</span><span style="FONT-FAMILY: 宋体">类型的对象。通过接口</span><span lang="EN-US">IMethodCallMessage </span><span style="FONT-FAMILY: 宋体">和</span> <span lang="EN-US">IMethodMessage</span><span style="FONT-FAMILY: 宋体">比通过接口</span><span lang="EN-US">IMessage</span><span style="FONT-FAMILY: 宋体">接口更容易实现对消息属性的访问。不必使用接口</span><span lang="EN-US">IDictionary</span><span style="FONT-FAMILY: 宋体">,仍可以直接访问方法名称、</span><span lang="EN-US">URI</span><span style="FONT-FAMILY: 宋体">和参数等内容。真实代理对象把</span><span lang="EN-US">ReturnMessage</span><span style="FONT-FAMILY: 宋体">返回给透明代理对象。</span></p>
<p align="center"><span lang="EN-US"><img height="214" src="16/image007.gif" width="561" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black">&nbsp; 16-7</span></p></div>
                <!-- page -->
                <div class="page" style="text-align: center">
                    <a href="100165473.htm">上一页</a>&nbsp;&nbsp;&nbsp;<a href="index.html">首页</a>&nbsp;&nbsp;&nbsp;<a href="100165475.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='100165474.htm'><font color='red'>16.5.4  对象的激活</font></a></h1>
                        <div id="divRealteNod2" style="padding-left: 2px">
                        <div style='float:left;width:49%'>·<a href='100165471.htm'>16.5.1  信道</a></div><div style='float:right;width:49%'>·<a href='100165472.htm'>16.5.2  格式标识符</a></div><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='100165475.htm'>16.5.5  消息接收器</a></div><div style='float:left;width:49%'>·<a href='100165476.htm'>16.5.6  在远程方法中传递对象</a></div><div style='float:right;width:49%'>·<a href='100165477.htm'>16.5.7  生存期管理</a></div></div>
                    </div>
                </div>
                </div>
        </div>
</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?