title author date CreateTime categories
WPF 从零开始开发 dotnet Remoting 程序
lindexi
2019-03-01 09:30:45 +0800
2018-08-30 20:36:53 +0800
WPF dotnet

本文告诉大家如何不使用框架,从零开始开发一个 dotnet remoting 程序

在我的另一篇博客 WPF 使用RPC调用其他进程 就大概告诉了大家如何在 WPF 使用 dotnet remoting 但是这篇博客是从大的方向告诉大家,所以本文就从代码上告诉大家如何写一个 dotnet remoting 做多进程框架。

首先需要创建几个项目,下面就是本文创建的项目

  • Native

    WPF 程序

  • Remote

    控制台项目

  • RemoteObject

    类库

引用项目

这里几个项目的应用关系是 Native 引用 Remote 和 RemoteObject 。在 Remote 项目引用 RemoteObject 项目。

这里的 Native 项目就是本地的 WPF 程序,而 Remote 控制台项目就是远程的进程,本文让 Native 作为主进程,让 Remote 进程做远程。

这里的 RemoteObject 就是放一些在 Native 和 Remote 都需要使用的类。

通过每个项目的用法就可以知道引用,因为我需要从 Native 启动 Remote ,在 VisualStudio 只要引用一个项目就可以让这个项目输出到项目所在的输出文件,所以就可以快速找到 Remote 进程。

现在尝试创建三个不同的项目,然后编译一下,这时就可以从 Native 的输出文件夹看到下面的文件

启动软件

在 Native 启动 Remote 很简单,因为在相同的文件夹,所以使用下面的代码启动

因为 Remote 只是一个控制台项目,为了让用户可以看到 Remote 就需要在主函数添加一些代码

        static void Main(string[] args)
{
Console.WriteLine("启动远程应用"); while (true)
{
Console.Read();
}
}

然后在 Native 的主页面添加下面代码

        public MainWindow()
{
InitializeComponent(); var processStartInfo = new ProcessStartInfo(ProgressName);
Process.Start(processStartInfo);
} private const string ProgressName = "Remote.exe";

现在运行一下 Native 就可以看到 Remote 也运行

注册类

现在尝试在远程 Remote 注册一个类,然后在本地调用 Remote 的这个类

先创建一个类请看代码

    [Serializable]
public class Addition : MarshalByRefObject
{
public int Add(int a, int b)
{
return a + b;
}
}

这个类先放在 RemoteObject 这样就可以在 Native 和远程都知道这个类

注册一个类的方法有很多个,本文只告诉大家通过 RemotingServices.Marshal 的方式注册

因为在 Remote 的主函数是等待输入也就是这个线程是无法使用,所以需要新创建一个线程

        static void Main(string[] args)
{
Console.WriteLine("启动远程应用"); var thread = new Thread(() =>
{
var addition = new Addition();
RemotingServices.Marshal(addition, "add");
})
{
IsBackground = true,
}; thread.Start(); while (true)
{
Console.Read();
}
}

现在就通过 RemotingServices.Marshal 注册了 Addition 类。

添加通道

为了让 Native 可以访问到 Remote 就需要 Remote 添加 Channel 让 Native 访问

在添加通道之前需要添加 .Net Remoting 的引用,右击三个项目添加引用,选择 System.Runtime.RemotingSystem.Runtime.Serialization 第一个就是基础支持第二个是用来序列化

使用下面的代码创建 TCPChannel 传入的参数就是端口

        private static IChannel CreatChannel()
{
var tcpServerChannel = new TcpServerChannel(8086);
return tcpServerChannel;
}

在传入的时候需要本地不存在冲突端口,也就是现在的端口没有被其他程序使用

通过这个方法就可以创建,创建之后需要注册,使用 ChannelServices.RegisterChannel 方法就可以注册,这个方法第二个参数是要不要使用安全传输

        static void Main(string[] args)
{
Console.WriteLine("启动远程应用"); var thread = new Thread(() =>
{
var addition = new Addition();
RemotingServices.Marshal(addition, "add"); _channel = CreatChannel();
ChannelServices.RegisterChannel(_channel, false);
})
{
IsBackground = true,
}; thread.Start(); while (true)
{
Console.Read();
}
} private static IChannel _channel; private static IChannel CreatChannel()
{
var tcpServerChannel = new TcpServerChannel(8086);
return tcpServerChannel;
}

现在就在 Remote 的准备完成了

在 Native 也需要注册通道才可以和 Remote 通信,在 Native 注册的 TCPChannel 是使用 TcpClientChannel 类,请看代码

        public MainWindow()
{
InitializeComponent(); var processStartInfo = new ProcessStartInfo(ProgressName);
Process.Start(processStartInfo); var tcpClientChannel = new TcpClientChannel();
ChannelServices.RegisterChannel(tcpClientChannel, false); }

现在就注册完成了,下面就是从 Native 调用远程的类

调用方法

在 Native 的界面添加一个按钮,在按钮按下的时候就触发 Remote 的类的函数

这里关于在 Native 的界面添加按钮和按钮事件本文就不说了,因为很简单。

在按钮按下的代码使用 Activator.GetObject 方法拿到远程的类

        private void Button_OnClick(object sender, RoutedEventArgs e)
{
var addition = (Addition) Activator.GetObject(typeof(Addition), "tcp://localhost:8086/add");
Debug.WriteLine(addition.Add(1, 2));
}

这里通过 8086 端口拿到刚才注册的 Addition 类,需要重新告诉大家 Addition 是如何注册的

                RemotingServices.Marshal(addition, "add");

在 RemotingServices 的 Marshal 第一个参数就是需要注册的类,第二个就是拿到这个类的链接

所以通过 tcp://localhost:8086/add 就可以拿到远程的类

现在点击按钮就可以看到输出 3 为了让大家知道是调用远程的方法,在 Addition 类添加输出

        public int Add(int a, int b)
{
Console.WriteLine(" 调用加法");
return a + b;
}

现在在 Native 按下按钮就可以看到 Native 的 VisualStudio 输出 3 同时 Remote 控制台输出 调用加法

上面就是最简单的使用 dotnet remoting 的例子,在接下来将会分为不同的细节来写很多篇博客。

先回忆一下,创建一个 .Net Remoting 需要经过哪些步骤

  1. 让 Native 引用 Remote 这样就可以让 Native 启动 Remote

  2. Remote 启动之后需要注册类,也就是给 Native 使用的类需要先注册

  3. 为了让 Native 和 Remote 通信就需要注册通信

  4. 通过 Activator.GetObject 拿到 Remote 的类返回透明代理

  5. 在 Native 通过 透明代理调用 Remote 的方法

在这个过程中几乎所有步骤都可以拿出来说

如果不想了解太多细节,想快速使用,请看WPF 封装 dotnet remoting 调用其他进程

参见:

Microsoft .Net Remoting系列专题之三:Remoting事件处理全接触 - 张逸 - 博客园

Microsoft .Net Remoting系列专题之二:Marshal、Disconnect与生命周期以及跟踪服务 - 张逸 - 博客园

In Depth .NET Remoting

Ingo Rammer,《Advanced .NET Remoting》

.net remoting 抛出异常

《Professional C#》 第3版

.NET Remoting程序开发入门篇-博客-云栖社区-阿里云

.NET Remoting中的事件处理(.NET Framework 2.0)(一) - 大坏蛋 - 博客园

WPF 使用RPC调用其他进程

2019-3-1-WPF-从零开始开发-dotnet-Remoting-程序的更多相关文章

  1. WPF 从零开始开发 dotnet Remoting 程序

    本文告诉大家如何不使用框架,从零开始开发一个 dotnet remoting 程序 在我的另一篇博客 WPF 使用RPC调用其他进程 就大概告诉了大家如何在 WPF 使用 dotnet remotin ...

  2. 使用 Tye 辅助开发 dotnet 应用程序

    newbe.pro 已经给我们写了系列文章介绍Tye 辅助开发k8s 应用: 使用 Tye 辅助开发 k8s 应用竟如此简单(一) 使用 Tye 辅助开发 k8s 应用竟如此简单(二) 使用 Tye ...

  3. WPF 封装 dotnet remoting 调用其他进程

    原文:WPF 封装 dotnet remoting 调用其他进程 本文告诉大家一个封装好的库,使用这个库可以快速搭建多进程相互使用. 目录 创建端口 调用软件 运行的类 运行C++程序 通道 使用 在 ...

  4. 使用VS Code从零开始开发调试.NET 5

    使用VS Code 从零开始开发调试.NET 5.无需安装VS 2019即可开发调试.NET 5应用. VS Code 全称是 Visual Studio Code,Visual Studio Cod ...

  5. 使用VS Code从零开始开发调试.NET Core 1.0

    使用VS Code 从零开始开发调试.NET Core 1.0. .NET Core 是一个开源的.跨平台的 .NET 实现. VS Code 全称是 Visual Studio Code,Visua ...

  6. 使用VS Code 从零开始开发并调试.NET Core 应用程序

    最新文章:http://www.cnblogs.com/linezero/p/VSCodeNETCore.html 使用VS Code 从零开始开发并调试.NET Core 应用程序,C#调试. 上一 ...

  7. 使用VS Code从零开始开发调试.NET Core 1.1

    使用VS Code 从零开始开发调试.NET Core 1.1.无需安装VS 2017 RC 即可开发.NET Core 1.1. .NET Core 1.1 发布也有一段时间了,最大的改动是从 pr ...

  8. WPF学习开发客户端软件-任务助手(下 2015年2月4日代码更新)

    时光如梭,距离第一次写的 WPF学习开发客户端软件-任务助手(已上传源码)  已有三个多月,期间我断断续续地对该项目做了优化.完善等等工作,现在重新向大家介绍一下,希望各位可以使用,本软件以实用性为主 ...

  9. WPF学习开发客户端软件-任务助手(已上传源码)

    本人纯属WPF新手,布局和WPF的开发水平相当欠缺,从个人来说,还是比较喜欢WPF的,有人说WPF是界面加上WINFORM,我不这样认为,WPF与WINFORM主要的不同在于数据绑定.   这个软件虽 ...

  10. WPF Multi-Touch 开发:高效开发模式

    原文 WPF Multi-Touch 开发:高效开发模式 在前几篇文章中已经介绍了触屏操作的多种模式,并对其开发方式也有了进一步了解.细心的朋友应该会发现在上一篇文章中,如果拖动图片过快它会因惯性效果 ...

随机推荐

  1. C++Builder 常用String

    关于AnsiSting的使用大全(1) arrow: Ansistring 转 char 代码: void __fastcall TForm1::Button1Click(TObject *Sende ...

  2. JavaSE_12_Properties类和缓冲流

    1.Properties类 java.util.Properties 继承于Hashtable ,来表示一个持久的属性集.它使用键值结构存储数据,每个键及其对应值都是一个字符串.该类也被许多Java类 ...

  3. 19-10-31-B

    %%%B哥 ZJ一下: 开题. 发现 语文考试???? 我不认识XD.老帅哥救我! 后来…… 对什么取模??? 什么玩意??输入什么?? 满足啥?? 全是亻 啊! 后来才知道是题楔×了 不管了. 然后 ...

  4. R语言数据预处理

    R语言数据预处理 一.日期时间.字符串的处理 日期 Date: 日期类,年与日 POSIXct: 日期时间类,精确到秒,用数字表示 POSIXlt: 日期时间类,精确到秒,用列表表示 Sys.date ...

  5. Jeecg-Boot 2.0 版本发布,基于Springboot+Vue 前后端分离快速开发平台

    目录 Jeecg-Boot项目简介 源码下载 升级日志 Issues解决 v1.1升级到v2.0不兼容地方 系统截图 Jeecg-Boot项目简介 Jeecg-boot 是一款基于代码生成器的智能开发 ...

  6. SQL Server日常积累

    1:      在Sql Server 中增加一列语句:  alter table table_name add column_name [not null] [references ....]  例 ...

  7. 验证sll证书与密钥

    $crtParse = openssl_x509_parse($ssl_content); //$ssl_content 证书内容 .crt文件内容 if (!$crtParse) { return ...

  8. JS--封装JS跳转页面函数

    //JS跳转页面 function gourl($iAlert,$iPage,$history='',$target="window") { if ($iAlert != &quo ...

  9. vue 编写插件

    1.    将插件逻辑封装成一个对象  最后在install编写业务代码暴露给Vue对象 好处: 可以添加任意参数在这个对象上 方便将install函数封装的更加精简 可拓展性也比较高 2.  将所有 ...

  10. Jquery选择器总结二

    简单选择器 1.:firstè选出匹配的元素中的第一个 2.:lastè选出匹配的元素中的最后一个 3.:eq(index)è选出匹配的元素中的指定索引位置的jquery对象(注:index从0开始) ...