.net中的命名管道(NamedPipe)
来源:互联网 发布:英语文章翻译软件 编辑:程序博客网 时间:2024/04/23 22:44
最近尝试代码分离,减少主程序中的代码,将很多Form都独立成单独的exe,主程序跟这些小程序间的通信就使用命名管道在进行。
之前运用过命名管道,但是是直接使用win32 api实现的,并且一直有问题,比如说有时候接收信息的阻塞被释放,但是又收不到任何东西。之前使用vs2005进行开发的,后来发现vs2010直接将命名管道封装成了类,就尝试使用了,发现比之前使用api时要顺手的多。
引用using System.IO.Pipes;这个命名空间,在vs2005中是没有此命名空间的,所以我将开发环境全部升级到了vs2010,还好升级比较方便。
我使用的情景都是阻塞式的,就是主程序调出某个exe后,主程序是无法运行的,必要等那个exe中程序执行完,或者关掉exe后,主程序才能响应。当然,如果需要做成非阻塞式的也是可以的,用线程或回调就行了。
vs2010自带的命名管道的类是分成服务器端跟客户端两个,有点类似使用soket的感觉,并且跟win32 api的方式也感觉不一样。win32 api的方式更像两边是对称的。
我封装了一个类,让软件调用的时候尽量的统一,不去区分服务器、客户端什么的。
下面是代码,注释写的应该也比较清楚。
using System;using System.Collections.Generic;using System.Text;using System.IO;using System.IO.Pipes;using System.Security.Principal;using System.Threading;using System.Diagnostics;namespace pipe{ public class NamedPipe : IDisposable { string err = ""; NamedPipeServerStream _pipeServer = null; NamedPipeClientStream _pipeClient = null; /// <summary> /// 初始化管道。每个进程发送与接收信息是两个管道进行通信。 /// 两个进程使用的管道名是相对的 /// 进程1使用的接收管道就是进程2使用的发送管道。进程2使用的发送管道就是进程1使用的接收管道。 /// </summary> /// <param name="server">监听管道的名称</param> /// <param name="client">发送管道名称</param> public NamedPipe(string server, string client) { try { _pipeServer = new NamedPipeServerStream(server, PipeDirection.InOut, 10); _pipeClient = new NamedPipeClientStream(".", client, PipeDirection.InOut); } catch (Exception ex) { err = ex.Message; } } public bool openExe(string path) { Process p = new Process(); try { p.StartInfo.FileName = path; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = true; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.Start(); return true; } catch (Exception ex) { err = ex.Message; return false; } finally { p.Close(); p.Dispose(); } } /// <summary> /// 读取错误信息 /// </summary> /// <returns></returns> public string Err() { string s; s = err; err = ""; return s; } /// <summary> /// 从管道中读取内容(阻塞式) /// </summary> /// <returns></returns> public string read() { try { if (!_pipeServer.IsConnected) { _pipeServer.WaitForConnection(); } string str = ""; StreamReader sr = new StreamReader(_pipeServer); while (_pipeServer.CanRead && (null != (str = sr.ReadLine()))) { Thread.Sleep(50); return str; } return str; } catch (Exception ex) { err = ex.Message; return ""; } } /// <summary> /// 往管道中写入内容 /// </summary> /// <param name="s">写入的内容</param> public bool send(string s) { try { if (!_pipeClient.IsConnected) { _pipeClient.Connect(); } StreamWriter sw = new StreamWriter(_pipeClient); sw.WriteLine(s); sw.Flush(); return true; } catch (Exception ex) { err = ex.Message; return false; } } #region IDisposable 成员 bool _disposed = false; public void Dispose() { try { if (!_disposed && _pipeServer != null) { _pipeServer.Close(); _pipeServer.Dispose(); } if (!_disposed && _pipeClient != null) { _pipeClient.Close(); _pipeClient.Dispose(); } _disposed = true; } catch (Exception ex) { err = ex.Message; } } #endregion }}
其实命名管道功能很强大,这里列举的只是在同一个电脑中两个进程间的通信,它甚至可以实现网络间的进程的通信,功能强大带来的开销以及效率肯定就是不太友好的,下一步准备来看看匿名管道,可能会更加符合我的应用场景。
0 0
- .net中的命名管道(NamedPipe)
- .net 命名管道(NamedPipe) 的使用
- .net 命名管道(NamedPipe) 的使用
- .net 命名管道(NamedPipe) 的使用
- C# NamedPipe 命名管道通信
- NamedPipe,利用命名管道实现进程间通信
- NamedPipe
- linux中的匿名管道和命名管道
- net指令 IPC$命名管道 学习
- .NET中的命名规则
- .NET中的命名规则
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- [linux 命令笔记] kill
- 枚举类型的构造方法
- iOS-绑定key与属性名方法
- PYTableViewController框架
- Freemarker使用之比较(if)
- .net中的命名管道(NamedPipe)
- 总结java.lang.Runtime
- DLNA 介绍
- 12.Tornado TCPServer类的设计解读 (副标题: 一个通用的server框架)
- OpenCV 图像反色 垂直翻转图像
- 5月份英语学习总结
- rk3288 uboot 编译问题
- java通过JDBC连接数据库
- Matlab安装 解决error114