实现进程之间煲电话粥的方式,有好几种,比如,你可以用这些方案:

1、使用socket来传递。这个好像很无聊,本地进程之间也用socket?不过,通过本机回环网络确实可以进程之间通信。

2、WCF,与上面的相似,也是利用本机回环地址来在进程间通信。

3、内存映射文件。这个可能有些朋友不太熟,毕竟平时装逼时也装不上这个。内存映射文件类似于磁盘中的物理文件,只不过它是存在于内存中的,一旦引用文件的最后一个进程退出,内存映射文件就会释放。多个进程间可以共享内存映文件来分享银行卡上的钱。

本文老周还介绍第 4 种方案——通过标准的输入/输出流来读写。输入流是向一个进程写入数据,相反地,输出流就是从某个进程读取数据。

原理不复杂,实现起来也不难,只需要用到一个我们都很熟悉的类:Console,这个类不仅可以在控制台应用程序中输入/输出文本,也可以用于标准流。

好,老周用一个例子来说明一下。

这个例子是这样的,假设有一个可执行文件,它没有UI,只是用于安装,在安装过程中,它会实时输出安装进度。然后,有另外一个程序,有窗口,这个程序会调用前面那个程序进行安装,并实时读出安装进度,显示到进度条控件上。

首先实现第一个程序,无窗口无UI无房无车,纯屌丝一个。

    class MainClass
{
static void Main()
{
BinaryWriter writer = new BinaryWriter(Console.OpenStandardOutput());
byte p = ;
do
{
writer.Write(p);
Thread.Sleep();
p++;
}
while (p <= );
writer.Close();
}
}

获取标准流,可以调用 OpenStandardOutput,或OpenStandardInput,这两个方法返回的流对象,可以灵活操作。还可以访问 Out / In 属性来获取标准流,它返回的是 TextReader 或 TextWriter,这用于读写文本较方便。

此处,老周只考虑写一个数值(0 - 100),所以,用 BinaryWriter 类操作会快乐一点。

这个项目,你既能生成为控制台应用程序,也可以是Windows应用程序,只要是.exe即可。

随后,我们实现有窗口有UI有房有车,纯壕一个。

            string exePath = @"..\..\..\SampleApp\bin\Debug\SampleApp.exe";
IProgress<int> prgs = new Progress<int>(p =>
{
progressBar1.Value = p;
}); ……
await Task.Run(() =>
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = exePath; //要执行的.exe文件
start.CreateNoWindow = true; //无窗口
start.UseShellExecute = false; //非Shell行为
start.RedirectStandardOutput = true; //必须,否则连毛都不出来
Process p = Process.Start(start);
BinaryReader reader = new BinaryReader(p.StandardOutput.BaseStream);
while (true)
{
byte prs = reader.ReadByte();
prgs.Report(prs);
if (prs == ) break;
}
reader.Close();
p.WaitForExit();
p.Close();
});
……

IProgress<T>是个好东西,它的实现类是 Progress<T>,只要我们在UI线程上把它实例化(即它的实例属于UI线程),那么在跨线程报告进度时会简便很多。实例化时,传一个Action<T>委托实例,用来回调进度。

启动进程前要准备一个 ProcessStartInfo,它可以设置一些参数。

如:

                ProcessStartInfo start = new ProcessStartInfo();
start.FileName = exePath; //要执行的.exe文件
start.CreateNoWindow = true; //无窗口
start.UseShellExecute = false; //非Shell行为
start.RedirectStandardOutput = true; //必须,否则连毛都不出来

反正安装程序是没有UI的,就让CreateNoWindow为真,不创建主窗口。另外,RedirectStandardOutput属性必须为真,不然我们代码就无法访问输入/输出流,只有重定向后的标准流才能在代码中使用。

运行结果如下图所示。

当然,你也可以用标准流来读写文本,或其他数据,这里读写数值,只作演示。

示例代码下载地址

【.net 深呼吸】通过标准输入/输出流来完成进程间通信的更多相关文章

  1. IO流(三)__字节流 标准输入输出流 转换流

    一.字节流:FileInputStream 和FileOutputStream 基本操作和字符流类相同,没有flush,但是close还是要的 复制一个字节流文件 private static voi ...

  2. 黑马程序员——JAVA基础之标准输入输出流

    ------- android培训.java培训.期待与您交流! ---------- 标准输入输出流: System中的基本字段,in,out 它们各代表了系统标准的输入和输出设备. 默认输入设备是 ...

  3. freopen()——重定向标准输入输出流

    freopen()——重定向标准输入输出流 头文件:stdio.h 函数原型:FILE * freopen(const char *filename , const char *type ,  FIL ...

  4. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  5. Java标准输入输出流的重定向及恢复

    在Java中输入输出数据一般(图形化界面例外)要用到标准输入输出流System.in和System.out,System.in,System.out默认指向控制台,但有时程序从文件中输入数据并将结果输 ...

  6. Java精选笔记_其他IO流(ObjectInputStream、DataInputStream、PrintStream、标准输入输出流)

    其他IO流 ObjectInputStream和ObjectOutputStream 如果希望永久将对象转为字节数据写入到硬盘上,即对象序列化,可以使用ObjectOutputStream(对象输出流 ...

  7. Java IO流-标准输入输出流

    2017-11-05 19:13:21 标准输入输出流:System类中的两个成员变量. 标准输入流(public static final InputStream in):“标准”输入流.此流已打开 ...

  8. 序列流、对象操作流、打印流、标准输入输出流、随机访问流、数据输入输出流、Properties(二十二)

    1.序列流 * 1.什么是序列流 * 序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开始读, 读完一个之后继续读第二个, 以此类推.* 2.使用方式 * 整合两个 ...

  9. java 标准输入输出流,打印流,数据流

    1 package stream; import static org.junit.Assert.assertNotNull; import java.io.BufferedReader; impor ...

随机推荐

  1. Android开发学习-view

    题记:抱着对Android开发的浓厚兴趣,加入了Study jams的线上学习小组,开启了自己的Android学习之旅.一.学习前准备:1.自己动手搭建了"Android Studio&qu ...

  2. 深入tornado中的协程

    tornado使用了单进程(当然也可以多进程) + 协程 + I/O多路复用的机制,解决了C10K中因为过多的线程(进程)的上下文切换 而导致的cpu资源的浪费. tornado中的I/O多路复用前面 ...

  3. JVM初探之类文件结构

    java 的 .class 文件字节码如图:Class 文件是一组以8字节为基础单位的二进制流,各个数据项目有着严格的结构.下面我们介绍下class文件的结构. 魔数 class文件的头4个字节是魔数 ...

  4. html列表问题

    HTML无序列表 无序列表是一个项目的列表,此列项目运用粗体圆点(典型的小黑圆圈)进行符号. 无序列表运用 标签 Coffee Milk 浏览器闪现如下: <ul "="&q ...

  5. AngularJS创建新指令 - 基本功能

    指令(Directives)是所有AngularJS应用最重要的部分.尽管AngularJS已经提供了非常丰富的指令,但还是经常需要创建应用特定的指令. AngularJS原有的指令 ng-init  ...

  6. 初学strurs基础

    Struts2基础学习总结 Struts 2是在WebWork2基础发展而来的. 注意:struts 2和struts 1在代码风格上几乎不一样. Struts 2 相比Struts 1的优点: 1. ...

  7. 揭秘Kafka高性能架构之道 - Kafka设计解析(六)

    原创文章,同步首发自作者个人博客.转载请务必在文章开头处以超链接形式注明出处http://www.jasongj.com/kafka/high_throughput/ 摘要 上一篇文章<Kafk ...

  8. LeanCloud 调研报告

    LeanCloud 是一家做后端即服务(BaaS)的厂商,目标是让移动互联网开发者能更加方便的开发应用. 出于工作关系,对 leancloud 进行了一番调研:主要目标是学习其后端即服务的产品化思路等 ...

  9. PHP 分支与循环

    一.概述: 上面一章我们讲解了PHP当中的运算符和表达式,通过上面的知识点我们就可以完成一些基本的运算操作了.但是涉及到一些比较复杂的逻辑,分支与循环就必不可少了.通过分支和循环的结合使用可以使业务更 ...

  10. Jenkins + Maven + Ansible + Tomcat 实现JAVA代码自动部署

    自动部署过程: jenkins从svn拉取代码,调用maven去打war包,用ansible去解压war包,最后重启tomcat. 前情回顾:在前面的文章我的环境已经有Jenkins+ansible ...