当前位置: 首页 > news >正文

在使用 .NET Remoting 技术开发跨进程通信时可能遇到的各种异常

在使用 .NET Remoting 开发跨进程应用的时候,你可能会遇到一些异常。因为这些异常在后验的时候非常简单但在一开始有各种异常烦扰的时候却并不清晰,所以我将这些异常整理到此文中,方便小伙伴们通过搜索引擎查阅。


本文内容

    • 连接到 IPC 端口失败: 系统找不到指定的文件
    • 找不到请求的服务
    • 信道“ipc”已注册

连接到 IPC 端口失败: 系统找不到指定的文件

System.Runtime.Remoting.RemotingException:“连接到 IPC 端口失败: 系统找不到指定的文件。”

或者英文版:

System.Runtime.Remoting.RemotingException: Failed to connect to an IPC Port: The system cannot find the file specified.

出现此异常时,说明你获取到了一个远端对象,但是在使用此对象的时候,甚至还没有注册 IPC 端口。

比如,下面的代码是注册一个 IPC 端口的一种比较粗暴的写法,传入的 portName 是 IPC 的 Uri 路径前缀。例如我可以传入 walterlv,这样一个 IPC 对象的格式大约类似 ipc://walterlv/xxx

private static void RegisterChannel(string portName)
{
    var serverProvider = new BinaryServerFormatterSinkProvider
    {
        TypeFilterLevel = TypeFilterLevel.Full,
    };
    var clientProvider = new BinaryClientFormatterSinkProvider();
    var properties = new Hashtable
    {
        ["portName"] = portName
    };
    var channel = new IpcChannel(properties, clientProvider, serverProvider);
    ChannelServices.RegisterChannel(channel, false);
}

当试图访问 ipc://walterlv/foo 对象并调用其中的方法的时候,如果连 walterlv 端口都没有注册,就会出现 连接到 IPC 端口失败: 系统找不到指定的文件。 异常。

如果你已经注册了 walterlv 端口,但是没有 foo 对象,则会出现另一个错误 找不到请求的服务,请看下一节。

找不到请求的服务

System.Runtime.Remoting.RemotingException:“找不到请求的服务”

或者英文版:

System.Runtime.Remoting.RemotingException: Requested Service not found

当出现此异常时,可能的原因有三个:

  1. 要查找的远端对象尚未创建;
  2. 要查找的远端对象已被回收;
  3. 没有使用匹配的方法创建和访问对象。

更具体来说,对于第一种情况,就是当你试图跨进程访问某对象的时候,此对象还没有创建。你需要做的,是控制好对象创建的时机,创建对象的进程需要比访问它的进程更早完成对象的创建和封送。也就是下面的代码需要先调用。

RemotingServices.Marshal(@object, typeof(TObject).Name, typeof(TObject));

而对于第二种情况,你可能需要手动处理好封送对象的生命周期。重写 InitializeLifetimeService 方法并返回 null 是一个很偷懒却有效的方法。

namespace Walterlv.Remoting.Framework
{
    public abstract class RemoteObject : MarshalByRefObject
    {
        public sealed override object InitializeLifetimeService() => null;
    }
}

而对于第三种情况,你需要检查你是如何注册 .NET Remoting 通道的,创建和访问方式必须匹配。

信道“ipc”已注册

System.Runtime.Remoting.RemotingException:“信道“ipc”已注册。”

在同一个进程中,IpcChannel 类的默认信道名称 IpcChannel.ChannelName 值是字符串 "ipc"。如果你不通过它的参数 properties 来指定 ["name"] = "另一个名称",那么你就不能重复调用 ChannelServices.RegisterChannel 来调用这个信道。

说简单点,就是上面的方法 RegisterChannel 你不能在一个进程中调用两次,即便 "portName" 不同也不行。通常你也不需要去调用两次,如果一定要,请通过 HashTable 修改 name 属性。


参考资料

  • c# - .Net remoting error “Requested Service not found” - Stack Overflow

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 使用 SetParent 跨进程设置父子窗口时的一些问题(小心卡死)
  • System.ComponentModel.Win32Exception (0x80004005): 无效的窗口句柄。
  • 解决 WPF 嵌套的子窗口在改变窗口大小的时候闪烁的问题
  • WPF 的 Application.Current.Dispatcher 中,为什么 Current 可能为 null
  • WPF 的 Application.Current.Dispatcher 中,Dispatcher 属性一定不会为 null
  • 提高使用 Visual Studio 开发效率的键盘快捷键
  • WPF 不要给 Window 类设置变换矩阵(分析篇):System.InvalidOperationException: 转换不可逆。
  • WPF 不要给 Window 类设置变换矩阵(应用篇)
  • git fetch 失败,因为 unable to resolve reference 'refs/remotes/origin/xxx': reference broken
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • 发现电脑屏幕总是不自动关闭?看看你是否打开了这些程序……
  • 临时编写和调试 C++ 代码?用 VSCode 就够了!一分钟搭好 C++ 调试环境
  • WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
  • 在 WPF 中获取一个依赖对象的所有依赖项属性
  • 如何在 WPF 中获取所有已经显式赋过值的依赖项属性
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Flannel解读
  • iOS 系统授权开发
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • JAVA多线程机制解析-volatilesynchronized
  • 记录一下第一次使用npm
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 力扣(LeetCode)357
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 最近的计划
  • 你对linux中grep命令知道多少?
  • kubernetes资源对象--ingress
  • puppet连载22:define用法
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (floyd+补集) poj 3275
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (安卓)跳转应用市场APP详情页的方式
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (六)c52学习之旅-独立按键
  • (生成器)yield与(迭代器)generator
  • (转)c++ std::pair 与 std::make
  • ... 是什么 ?... 有什么用处?
  • ../depcomp: line 571: exec: g++: not found
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .Net Core缓存组件(MemoryCache)源码解析
  • .Net6使用WebSocket与前端进行通信
  • .net网站发布-允许更新此预编译站点
  • @Autowired自动装配
  • @configuration注解_2w字长文给你讲透了配置类为什么要添加 @Configuration注解
  • [ NOI 2001 ] 食物链
  • [④ADRV902x]: Digital Filter Configuration(发射端)
  • [AI]文心一言出圈的同时,NLP处理下的ChatGPT-4.5最新资讯
  • [Angularjs]ng-select和ng-options
  • [AR]Vumark(下一代条形码)
  • [BZOJ]4817: [Sdoi2017]树点涂色
  • [IMX6DL] CPU频率调节模式以及降频方法
  • [leetcode] Balanced Binary Tree