.Net组件程序设计之远程调用(一)

1应用程序域

我们知道我们写的C#代码是在操作系统逻辑体系结构中最上层的,然而操作系统本身是不会认识C#代码的,它只认识机器代码。那我们写的程序经过编译后是编译成IL的,是怎么运行的呢?实际是在一个托管的环境下运行的,是.NET提供的支持,操作系统是不会识别IL的,这中间就需要一个桥梁:应用程序域。操作系统中的进程是资源单位,应用程序域的执行使用当然也要占用空间使用资源了,所以是物理进程承载着应用程序域的,而且这种承载关系并不是一对一的。

图:应用程序域

使用应用程序域这样的机制,是有许多好处的。比如说客户端在调用其他组件的时候可以创建一个应用程序域,然后在新建的应用程序域中加载组件进行操作等等,即使被调用的组件发生一些致命的错误也不会导致客户端崩溃,有效的进行了错误隔离。还有一些数据交互传输上的性能差异等等,这里不做详细的阐述了。

2.NET Remoting

.NET Remoting是一种基于.NET平台的分布式系统框架,所了解的就是用于数据传输。 说几句它被使用的局限性很大,受到了平台的限制,当然如果仅仅是这样是不能否定它的强大和几乎无限扩展的框架体系,无论在哪一个环节你都可以自己来实现一些自定义的功能。会在下个篇幅稍作讲解。

3.AppDomain

在.NET中用AppDoMain类来表示应用程序域,也提供了获取当前应用程序域的方法,可以直接使用AppDoMain类的静态属性CurrentDomain来获取到当前程序所在的应用程序域,这是一种方法,还额外提供一种了,就是Thread类的GetDomain()静态方法也是可以获取到的。

3.1 在当前应用程序域中创建对象

 namespace RemoteServer
public class class1
{
private string appDoMainName; public class1()
{
appDoMainName = AppDomain.CurrentDomain.FriendlyName;
} public void Writer()
{
Console.WriteLine(appDoMainName);
}
}

class1中构造函数是获取当前应用程序域的名称,并且是在Writer()方法中输出到控制台界面中,

using RemoteServer;

namespace RemoteCase
{
AppDomain appDoMain = AppDomain.CurrentDomain;
class1 cls1 = (class1)appDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1");
cls1.Writer();
}

图3-1

这里使用了AppDomain中的静态方法CreateInstanceFromAndUnwrap(),因为当前项目已经引用了RemoteServer程序集,所以第一个参数只是一个显示的名称,并不是全路径,在调用方法的时候,应用程序域会加载程序集,用于获取到元数据。

3.2 在新建应用程序域中创建对象

 namespace RemoteServer
public class class1:MarshalByRefObject
{
private string appDoMainName; public class1()
{
appDoMainName = AppDomain.CurrentDomain.FriendlyName;
} public void Writer()
{
Console.WriteLine(appDoMainName);
}
}
 using RemoteServer;

       AppDomain appDoMain = AppDomain.CurrentDomain;
AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain");
class1 cls1 = (class1)newDoMain.CreateInstanceFromAndUnwrap("RemoteServer.dll", "RemoteServer.class1");
cls1.Writer();

图3-2

3.3 拆包远程对象

图3-3-1

这段代码是3.2中的代码,cls1并不是class1类型本身,而是代理,访问远程对象都是通过代理完成的,这么屌炸天的.NET当然提供优化,将创建远程对象和在客户端建立代理分离,这样可以在你创建了一个远程对象之后再建立代理。 AppDomain类提供了一套CreateInstance()方法来创建对象,但是都以ObjectHandle的形式返回一个远程对象句柄(意思就是远程对象的唯一标示,这个句柄能代表远程对象)

ObjectHandle对象实现了System.Runtime.Remoting命名空间下的IObjectHandle接口:

 namespace RemoteServer
public class class1:MarshalByRefObject
{
private string appDoMainName; public class1()
{
appDoMainName = AppDomain.CurrentDomain.FriendlyName;
} public void Writer()
{
Console.WriteLine(appDoMainName);
} }
 using RemoteServer;

             AppDomain appDoMain = AppDomain.CurrentDomain;
AppDomain newDoMain = AppDomain.CreateDomain("NewDoMain");
IObjectHandle objecthandle;
objecthandle = newDoMain.CreateInstance("RemoteServer", "RemoteServer.class1"); RemoteServer.class1 cls1 = objecthandle.Unwrap() as RemoteServer.class1; cls1.Writer();

一般情况下是不需要手动拆包对象句柄的,这样做的好处只是可以推迟加载RemoteServer程序集,只有在 objecthandle.Unwrap()的时候才会建立代理,而建立代理必须需要对象元数据。

4远程对象类型

一般情况下,被引用对象和客户端同在一个应用程序域,这样的情况下不涉及到代理,也不会用到什么远程调用,

而是直接引用对象,如果当你需要调用另一个应用程序域里的对象时会是什么样的?默认情况下.NET是不允许对象跨应用程序域访问的,

不管是不是在同一个进程内。但是呢如果要访问,也不是不行的,.NET提供了两种数据传递方式,一种是值传递,一种是引用传递

4.1按值封送

当应用程序域A调用应用程序域B中的对象时,应用程序域B中的对象会被拷贝一个克隆到应用程序域A,这时候两个对象是不存在任何关系的,这种情况叫做按值封送    一般情况下都是使类型使用Serializable特性,支持序列化,通过序列化来达到按值封送的目的,在被调用方序列化,到调用方反序列化。

4.2引用封送

这种情况就是当应用程序域A调用应用程序域B的对象时,应用程序域A获得的是应用程序域B中对象的引用,

这个引用挂在哪里呢?挂在应用程序域A的对象代理上,这种情况就叫引用封送    引用封送就比按值封送有意思多了,想要满足可以引用封送的要求,则对象必须继承自MarshalByRefObject,MarshalByRefObject类型给出的解释就是 允许在支持远程处理的应用程序中跨应用程序域边界访问对象,这样作为它的子类同样的也享受这样的优待。在引用封送中会有两种远程对象激活模式,这个内容在下一个篇幅中会有详细的示例代码。

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

.Net组件程序设计之远程调用(一)的更多相关文章

  1. .Net组件程序设计之远程调用(二)

    .Net组件程序设计之远程调用(二) 激活模式 引用封送对象激活类型两种, 一种是客户端激活类型,一种是服务器端激活. 客户端激活对象 客户端激活方式:当客户端创建一个远程对象时,客户端得到的是一个新 ...

  2. .Net组件程序设计之异步调用

    .Net组件程序设计之异步调用 说到异步调用,在脑海中首先想到就是BeginInvoke(),在一些常用对象中我们也会常常见到Invoke()和BeginInvoke(), 要想让自己的组件可以被客户 ...

  3. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  4. zookeeper系列之七—从远程调用认识zookeeper

    http://www.csdn.net/article/2014-01-02/2817944-zookeeper 在Hadoop的学习过程中,Zookeeper是让很多初学者困惑的技术,远程调用服务是 ...

  5. 如何从零开始实现一个soa远程调用服务基础组件

    说起soa远程调用基础组件,最著名的莫过于淘宝的dubbo了,目前很多的大型互联网公司都有一套自己的远程服务调用分布式框架,或者是使用开源的(例如dubbo),或者是自己基于某种协议(例如hessia ...

  6. .Net组件程序设计之上下文

    .Net组件程序设计之上下文 在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?没错了,就是上下文.CLR把应用程序域更细化了,在应用程 ...

  7. .Net组件程序设计

    .Net组件程序设计之上下文 在后续篇幅的远程调用的文章里有说到应用程序域,那是大粒度的控制程序集的逻辑存在,那么想对对象的控制又由谁来做主呢?没错了,就是上下文.CLR把应用程序域更细化了,在应用程 ...

  8. 架构设计:一种远程调用服务的设计构思(zookeeper的一种应用实践)

    在深入学习zookeeper我想先给大家介绍一个和zookeeper相关的应用实例,我把这个实例命名为远程调用服务.通过对这种应用实例的描述,我们会对zookeeper应用场景会有深入的了解. 远程调 ...

  9. .NET组件程序设计之线程、并发管理(二)

    .Net组件程序设计之线程.并发管理(二) 2.同步线程 手动同步 监视器 互斥 可等待事件 同步线程 所有的.NET组件都支持在多线程的环境中运行,可以被多个线程并发访问,如果没有线程同步,这样的后 ...

随机推荐

  1. Matlab 读取文件夹中所有的bmp文件

    将srcimg文件下的bmp文件转为jpg图像,存放在dstimg文件夹下 str = 'srcimg'; dst = 'dstimg'; file=dir([str,'\*.bmp']); :len ...

  2. linux下安装apache与php;Apache+PHP+MySQL配置攻略

    1.apache   在如下页面下载apache的for Linux 的源码包    http://www.apache.org/dist/httpd/;   存至/home/xx目录,xx是自建文件 ...

  3. [leetcode] 数字游戏

    169. Majority Element Given an array of size n, find the majority element. The majority element is t ...

  4. python调用c\c++

    前言 python 这门语言,凭借着其极高的易学易用易读性和丰富的扩展带来的学习友好性和项目友好性,近年来迅速成为了越来越多的人们的首选.然而一旦拿python与传统的编程语言(C/C++)如来比较的 ...

  5. LINUX 常用命令 ps 详解

    ps常用命令 ps -u ceshi 查看特定用户(ceshi)进程的情况 ps aux | grep nginx 查找nginx的进程 pa -ef | grep nginx 查找nginx的进程 ...

  6. [bzoj4722]由乃

    身为10班人,就凭标题,这道题是一定要做的. 但是做了才发现有毒....所以是信念和题解和大腿支撑了我! 先"假设"自己实力过硬,推出了结论:当区间过大时,必定存在一种方案可以输出 ...

  7. 支付宝推AR实景红包,抢红包得拼脑力和体力

    近年春节,各大互联网平台都会借机掀起"红包大战",其中支付宝和微信的红包玩法备受用户关注.今年,微信尚未公布春节红包相关的方案信息,不过,今天支付宝率先推出"AR实景红包 ...

  8. 阅读jquery源码与js依赖加载的模块化!

    阅读源码肯定是先下载有注释的源码 我也是醉了,10309 行代码,在陆续续的一个月之内,看完了,虽有收获但收获不大, 直到又一次看jquery的github,怎么会有cmd????没听过使用jquer ...

  9. 文档:网络通讯包结构(crc校验,加解密)

    一直想把这个流程整理一下. 包结构: 包 对(datacrc+protoID+dataSize)组成的byte[] 进行crc计算而得到 对(数据内容)进行crc计算而得到 协议号 数据内容的字节长度 ...

  10. js学习笔记之标准库

    在全局函数中,this等于window  在函数被作为某个对象的方法调用时,this等于那个对象. 数组的函数: 检测:Array.isArray() 转换:toString(),toLocalStr ...