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. mysql联表查询,使用phpStudy自带的

    一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2.外联结:分为外左 ...

  2. input 的 placeholder 样式修改

    input::-webkit-input-placeholder{ color:#999999; } input::-moz-placeholder{ /* Mozilla Firefox 19+ * ...

  3. 嵌入式开发—C语言面试题

    嵌入式开发—C语言面试题 源地址:http://blog.csdn.net/xdx2ct1314/article/details/7358929   1. 用预处理指令#define 声明一个常数,用 ...

  4. 基于vue-cli的vs code设置

    vue-cli自带eslin校验,vs code采用下可以设置在保存文件时会自动纠正格式 { // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detec ...

  5. AutoMapper简介

    先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...

  6. iOS 更新日志 - 持续更新中

    本文只是为了简单记录一下每个正式版本发布时间和更新内容,只有这个初衷,从2019年9月25日开始,将会持续更新. iOS 13.1 - 2019年9月25日 iOS 13.1 iOS 13.1 包括错 ...

  7. HZOI2019 超级树 dp

    题面:https://www.cnblogs.com/Juve/articles/11207540.html(密码)————————————————>>> 题解: 官方题解: 考虑d ...

  8. Ionic 图片预览ion-slide-box,ion-slide,ion-scroll实现

    1.index.html 代码 <body ng-app="starter"> <ion-pane> <ion-header-bar class=&q ...

  9. 垂直对齐:vertical-align属性——使用中注意事项

    1.vertical-align(垂直对齐),只对行内元素和单元格元素有效,例如属性为inline和inline-block的元素以及图片.输入表单等都是行内元素; 2.元素默认的垂直对齐方式为基线对 ...

  10. hibernate 注释多表 级联操作

    一对多模型(单向) 说明: 一个客户对应多个地址,通过客户可以获得该客户的多个地址的信息.客户和地址是一对多的关系,并且客户与地址是单向关联的关系. 映射策略 # 外键关联:两个表的关系定义在一个表中 ...