C#讲义-18 Remoting_第1页
C#讲义-18 Remoting_第2页
C#讲义-18 Remoting_第3页
C#讲义-18 Remoting_第4页
C#讲义-18 Remoting_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1 18 Remoting n进程 n应用程序域 n应用程序域和程序集 n应用程序域和线程 n例子: n远程对象分布式计算 n异步调用 2 进程 n进程是操作系统用于隔离众多正在运行的应用程序的机制。 n在Net之前,每一个应用程序被加载到单独的进程中,并为该 进程指定私有的虚拟内存。一个进程不可能访问分配给另一个进 程的内存。相应地,运行在该进程中的应用程序也不可能写入另 一个应用程序的内存,确保任何执行出错的代码不会损害其地址 空间以外的应用程序。 n缺点:降低了性能。许多一起工作的进程需要相互通信,而进程 却不能共享任何内存,不能通过任何有意义的方式使用从一个进 程传递到另一个进程的内存

2、指针。此外,不能在两个进程间进行 直接调用。必须代之以使用代理,它提供一定程度的间接性。 n进程间通讯。 n进程切换。 3 应用程序域 n在Net中,应用程序新的边界:应用程序域。应用程序域。应用程序域提供 了一个更安全、用途更广的处理单元,公共语言运行库使用该单 元提供应用程序之间的隔离。 单个进程中运行几个应用程序域,而不会造成进程间调用或 进程间切换等方面的额外开销。 域之间通讯比进程间通讯方便。 域之间不存在切换。 一个域中的应用程序不能直接访问另一个域中的代码和数据。 在一个应用程序中出现的错误不会影响其他应用程序 能够在不停止整个进程的情况下停止单个应用程序 ,可以卸 载在单个应用

3、程序中运行的代码 4 应用程序域和程序集 n在可以执行程序集中所包含的代码之前,必须将程序集加载到应 用程序域中。 n可以将几个程序集加载到一个应用程序域中 。 n程序集的加载方式决定其实时 (JIT) 编译代码是否可以在进程中 由多个应用程序域共享,以及该程序集是否可以从进程中卸载。 以非特定于域的形式进行加载 ,所有应用程序域共享 ,程序 集不能从进程中卸载 。 特定于域的形式进行加载,通过卸载程序集加载的应用程序 域,可以从进程中卸载程序集 。 5 应用程序域和线程 n线程是公共语言运行库用来执行代码的操作系统内核对象。托管 代码均加载到某一个应用程序域中,由托管线程来运行。 n应用程序

4、域和线程之间不具有一对一的相关性。 在任意给定时间,在单个应用程序域中可以执行几个线程。 在任意给定时间,每一线程都在一个应用程序域中执行 线程并不局限在单个应用程序域内。线程可以自由跨越应用 程序域边界。 通过调用 GetDomain 方法,可以随时确定线程执行所在的域 6 默认域 n对多数应用程序,并不必须创建域,每次CLR在初始化一个进程 时,将创建默认域,并使该进程运行于这个默认域下。然而,默 认域不能由任何系统调用来卸载,该域只有在进程被卸载之后才 能被销毁。 7 AppDomain类 nAppDomain 类是域的编程接口,包含有大量的方法能完成各种管 理任务,主要有: 创建域 A

5、ppDomain myDomain = AppDomain.CreateDomain(MyDomain); 加载程序集 myDomain .Load(AssemblyName); 加载某程序集的某类型 ObjectHandle oh= myDomain.CreateInstance (“AssembleName,classname); 卸载域 AppDomain.Unload(myDomain); / 静态方法 8 例子: namespace RemoteLib Serializable /Serializable Attribute 指示该类型的实例可以通过某通道序列化 public cla

6、ss rmtcls /:System.MarshalByRefObject public int id get;set; public rmtcls() id = 0; public string whereami() return AppDomain.CurrentDomain.FriendlyName ; 编译此类,得到一个装配件remoteclass.dll 9 创建客户程序RemoteClient 该应用首先要引用装配件,并引用其名称空间。 引用System.Runtime.Remoting; private void button1_Click(object sender, Even

7、tArgs e) MessageBox.Show (AppDomain.CurrentDomain.FriendlyName.ToString(); AppDomain ad2=AppDomain.CreateDomain (newdom); ObjectHandle oh=ad2.CreateInstance (RemoteLib,RemoteLib.rmtcls);/新域中创建一个对象。 rmtcls l=new rmtcls ();/主域中创建的对象。 rmtcls r=(rmtcls)oh.Unwrap();/新域中的对象串行化到主域中 来。 MessageBox.Show(l.whe

8、reami(); MessageBox.Show(r.whereami(); 10 n运行结果: RemoteClient.exe / 默认域 RemoteClient.exe / 本地对象 RemoteClient.exe / 新域中串行化过来的对象 两个对象的返回值一样。都在主域中运行。 n把对象改为如下: /Serializable public class rmtcls:System.MarshalByRefObject 则运行结果完全不同: RemoteClient.exe / 默认域 RemoteClient.exe / 本地对象 Newdom / 远端代理 11 n应用程序域是进

9、程中一个或多个应用程序所驻留的分区。同一应 用程序域中的对象直接通讯。不同应用程序域中的对象的通讯方 式有两种: 跨应用程序域边界传输对象副本。具有Serializable特性的对 象根据值值隐式封送。当远程应用程序引用根据值封送的对象 时,将跨应用程序域边界传递该对象的副本。 使用代理交换消息。MarshalByRefObject 是通过使用代理交 换消息来跨应用程序域边界进行通讯的对象的基类。 MarshalByRefObject 对象在本地应用程序域的边界内可直接 访问。远程应用程序域中的应用程序首次访问 MarshalByRefObject 时,会向该远程应用程序传递代理。对 该代理后

10、面的调用将封送回驻留在本地应用程序域中的对象。 12 如加上以下代码: r.id = 3;/ 在本地对r进行修改 rmtcls r2 = (rmtcls)oh.Unwrap(); / 对远程域中的对象再一次反串 行化 MessageBox.Show(r2.id.ToString(); n如使用代理的方式: 输出3 因为只有一个实体。 n如使用副本的方式: 输出0。有两个独立的实体 13 如再加上: AppDomain.Unload(newdom); MessageBox.Show (r.whereami(); n代理方式上述s=r.whereami ();会失败。 n而副本方式则没有影响。子域

11、的对象被列集到主域中。 14 远程对象 public class rmtcls:System.MarshalByRefObject / 远程对象应使用代理方式 public int id get;set; public rmtcls() id = 0; public string whereami() return AppDomain.CurrentDomain.FriendlyName ; public int AddID() return +id; 15 远程服务器: 引用远程对象配件 引用System.Runtime.Remoting组件。 using System.Runtime.Re

12、moting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; TcpServerChannel channel=new TcpServerChannel (8086); ChannelServices.RegisterChannel (channel,true); RemotingConfiguration.RegisterWellKnownServiceType (typeof(rmtcls), hello, WellKnownObjectMode. SingleCall

13、); /如果改为Singleton 则 16 n客户端: n引用远程对象配件 n引用System.Runtime.Remoting组件。 using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; ChannelServices.RegisterChannel (new TcpClientChannel () ,true); rmtcls r=(rmtcls)Activator.GetObject (typeof(rmtcls),tcp:/localhost:8086/hello); M

14、essageBox.Show (r.whereami (); /返回RemoteServer.exe MessageBox.Show (r.AddId ().ToString() ); MessageBox.Show (r.AddId ().ToString() ); /两行均返回1。 /如果改为Singleton 则分别为1,2。 17 nRemotingConfiguration用于为激活服务器对象注册远程对象类。 nsingleCall n对象不保存状态,每一次调用远程对象时,都会创建一个新的实 例。 nSingleton n服务器的所有客户共享对象。可以用于在客户之间共享数据。 18

15、设置通道属性 IDictionary properties = new Hashtable(); propertiesname = TCP Channel with a SOAP Formatter; propertiespriority = 20; propertiesport = 8086; SoapServerFormatterSinkProvider sinkProvider =new SoapServerFormatterSinkProvider(); /两种格式化的方式。Binary,Soap。 TcpServerChannel tcpChannel = new TcpServer

16、Channel(properties, sinkProvider); 19 nChannelServices 把通道注册到.net Remoting n运行时中。 20 异步调用 n服务器函数调用时间很短时可以使用同步的方式进行。 n如果事件很长时,客户端不能承受长事件的等待时,则应考虑如 下的方法: 客户端开辟工作线程来完成。 客户端使用异步的调用。 21 nNET Framework 允许异步调用任何方法。定义与需要调用的方法 具有相同签名的委托;公共语言运行库将自动为该委托定义具有适 当签名的 BeginInvoke 和 EndInvoke 方法。 nBeginInvoke 方法用于启动

17、异步调用。它与需要异步执行的方法具 有相同的参数,只不过还有两个额外的参数.BeginInvoke不等待异 步调用完成立即返回IAsyncResult 。可用于监视调用进度。 nEndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可 随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将 一直阻塞到异步调用完成。EndInvoke 的参数包括需要异步执行 的方法的 out 和 ref 参数以及由 BeginInvoke 返回的 IAsyncResult。 22 n调用了 BeginInvoke 后,可以选择: 进行某些操作,然后调用 EndIn

18、voke 一直阻塞到调用完成。 使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使 用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。 轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用 何时完成,然后调用 EndInvoke。 将用于回调方法的委托传递给 BeginInvoke。该方法在异步 调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。 23 为了演示参数的使用,函数改为: public string whereami(int

19、i,out int o) System.Threading .Thread .Sleep (10000); /为了模仿耗时的操作,休眠10秒。 o=i*i; return AppDomain.CurrentDomain.FriendlyName ; 24 public delegate string whereDel(int i,out int o);/定义一个委托,它与 欲异步调用的方法具有同样的签名。 private void button2_Click(object sender, System.EventArgs e) ChannelServices.RegisterChannel (

20、new TcpClientChannel (),true); rmtcls r=(rmtcls)Activator.GetObject (typeof(rmtcls), “tcp:/localhost:8086/hello”); /得到远程对象的引用 whereDel del=new whereDel (r.whereami ); /以远程对象的方法来实例化一个委托。 int o; IAsyncResult ar=del.BeginInvoke (3,out o,null,null); / 开始异步调用,第一个null表示回调函数。第二个函数表示执行 状态。此函数立即返回。 MessageBo

21、x.Show (o.ToString (); /此时o中无值。 /此时可以做别的事情。 string s=del.EndInvoke (out o,ar); /来取结果,如果异步调用未 完成,比如说10秒不到,函数会阻塞,直至完成为止。 MessageBox.Show (s); /得到结果。 MessageBox.Show (o.ToString (); /得到输出参数结果 25 n在s=del.EndInvoke (out o,ar); 之前: 可以加上ar.AsyncWaitHandle .WaitOne ();会阻塞当前线程直 到异步调用完成并发出信号为止。这样再次调用EndInvoke时 就直接完成,不会阻塞。 或者先通过 异步结果IAsyncResult来轮询判断 while(ar.IsCompleted = false) Thread.Sleep(10); 这几种方法效果是相当的。 26 n如果启动异步调用的线程不需要处理调用结果,则可以在调用完 成时执行回调方法。回调方法在 ThreadPool 线程上执行。 n要使用回调方法,必须将代表该方法的 AsyncCallb

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论