您的位置:首页 > 编程语言 > C#

c# 进程间通信 IPC

2015-02-17 22:30 441 查看

c# 进程间通信 IPC

最近在调试一个算法,想通过改变算法的参数看看结果有什么变化。 碰到一个麻烦的事情是,从磁盘加载、构建数据需要15分钟。这就比较讨厌了,也就是说我每次调一个参数前都要等15分钟启动时间?

于是我就想,能不能开一个datahost进程专门加载数据。我在别的进程调试参数,但需要用数据时就直接从datahost进程中加载现成的数据。 这样的话我只需要从磁盘加载一次数据。 于是找了一下, c#有个叫IPC(inter process communication)的功能可以实现同一台机器上的不同进程间通信。

注意我这里的scenario:我需要进程间通信“数据对象”, 而不是消息。 通信消息比较好办,就传一个string流就行了。而我需要传递的是数据对象,比如一个Dictionary, 或者自定义class。

IPC的大致过程是这样的:datahost进程先绑定一个对象,client根据对象的uri去访问对象类, 并且调用该类的方法。datahost进程接收到从client发来的调用,就会实例化一个对象(注意,在这个时候才开始实例化一个对象,这也是我的代码里使用static的原因),并且执行相关的函数,再把结果返回给client。 注意执行过程是在datahost端的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IPCServer
{
public class DataObj : MarshalByRefObject
{
public static Dictionary<string, int> salary;
public static string company;
public static int counter;

public static int constructerCnt = 0;

public static void LoadData()
{
company = "Microsoft";
salary = new Dictionary<string, int>();
salary.Add("lianjx", 3);
salary.Add("uncle", 5);
counter = 0;
}

public Dictionary<string, int> GetSalary()
{
return DataObj.salary;
}

public DataObj()
{
DataObj.constructerCnt++;
Console.WriteLine("Constructer...{0}", DataObj.constructerCnt);
}

}
}


1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Runtime.Remoting;
5 using System.Runtime.Remoting.Channels;
6 using System.Runtime.Remoting.Channels.Ipc;
7 using System.Text;
8 using System.Threading.Tasks;
9
10 namespace IPCServer
11 {
12     class Program
13     {
14         static void Main(string[] args)
15         {
16             IpcServerChannel channel = new IpcServerChannel("ServerChannel");
17             ChannelServices.RegisterChannel(channel, false);
18             DataObj.LoadData();
19             DataObj.salary.Add("jian", 23);
20             DataObj.salary.Add("xun", 22);
21             RemotingConfiguration.RegisterWellKnownServiceType(typeof(DataObj), "DataObj", WellKnownObjectMode.SingleCall);
22
23             Console.WriteLine("press anykey to exit");
24             Console.ReadKey();
25         }
26     }
27 }


1 using IPCServer;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Runtime.Remoting.Channels;
6 using System.Runtime.Remoting.Channels.Ipc;
7 using System.Text;
8 using System.Threading.Tasks;
9
10 namespace IPCClient
11 {
12     class Program
13     {
14         static void Main(string[] args)
15         {
16             IpcClientChannel channel = new IpcClientChannel();
17             ChannelServices.RegisterChannel(channel, false);
18
19             DataObj obj = null;
20
21             for (int t = 0; t < 1; t++)
22             {
23                 Console.WriteLine("t={0}", t);
24                 try
25                 {
26                     obj = (DataObj)Activator.GetObject(typeof(DataObj), "ipc://ServerChannel/DataObj");
27                 }
28                 catch (Exception e)
29                 {
30                     Console.WriteLine(e.Message);
31                 }
32
33                 if (obj == null)
34                 {
35                     Console.WriteLine("could not locate server");
36                 }
37                 else
38                 {
39                     foreach (var pair in  obj.GetSalary())
40                     {
41                         Console.WriteLine("{0},{1}", pair.Key, pair.Value);
42                     }
43                     Console.WriteLine("counter = {0}", obj.GetSalary());
44                     DataObj.counter++;
45                 }
46             }
47
48             Console.WriteLine("Mission Complete!");
49             Console.ReadKey();
50         }
51     }
52 }


事实上结果并没有加速。估计IPC也是把对象序列化后传递,再反序列化的吧。 桑心。

next steps: 寻找一种直接读其他进程的内存空间的途径。。。

分类: c#
标签: IPC, 进程间通信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: