创建第二个.NET远程连接时遇‘Type is not registered for activation’错误求助
.NET远程连接中Connection2实例化报错及优化建议
问题背景
原有connect()函数稳定运行12年,可正常连接单个服务器端应用。今年需连接部署在另一台机器上的同款服务器应用,因此复制该函数并新增Connection2类(因客户端单个类仅能注册一次)。但connect()可正常运行,connect2()却在执行remoteServer2 = New Connection2时抛出Type is not registered for activation错误。
客户端相关代码
Private Function connect(Optional ByVal forceConnect As Boolean = False) As Boolean Dim channel As TcpClientChannel Try If Not remoteServer Is Nothing And Not forceConnect Then Exit Function 'don't reconnect 'unregister first in case we are connecting after a failure channel = ChannelServices.GetChannel("server") ChannelServices.UnregisterChannel(channel) Dim serverProv As BinaryServerFormatterSinkProvider = New BinaryServerFormatterSinkProvider serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full Dim clientProv As BinaryClientFormatterSinkProvider = New BinaryClientFormatterSinkProvider System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(New TcpClientChannel("server", clientProv), False) Try RemotingConfiguration.RegisterActivatedClientType(GetType(Connection), server) Catch ex As Exception 'resume End Try remoteServer = New Connection Catch ex As System.Net.Sockets.SocketException MsgBox("The server is not started" & vbCrLf & vbCrLf & server, MsgBoxStyle.Critical, "Error") channel = ChannelServices.GetChannel("server") ChannelServices.UnregisterChannel(channel) Return False Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "Error!!") channel = ChannelServices.GetChannel("server") ChannelServices.UnregisterChannel(channel) Return False End Try Return True End Function Private Function connect2(Optional ByVal forceConnect As Boolean = False) As Boolean Dim channel2 As TcpClientChannel Try If Not remoteServer2 Is Nothing And Not forceConnect Then Exit Function 'don't reconnect 'unregister first in case we are connecting after a failure channel2 = ChannelServices.GetChannel("server2") ChannelServices.UnregisterChannel(channel2) Dim serverProv2 As BinaryServerFormatterSinkProvider = New BinaryServerFormatterSinkProvider serverProv2.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full Dim clientProv2 As BinaryClientFormatterSinkProvider = New BinaryClientFormatterSinkProvider System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(New TcpClientChannel("server2", clientProv2), False) Try RemotingConfiguration.RegisterActivatedClientType(GetType(Connection2), server2) Catch ex As Exception 'resume End Try remoteServer2 = New Connection2 ' ---- EXCEPTION OCCURS HERE Catch ex As System.Net.Sockets.SocketException MsgBox("The server2 is not started" & vbCrLf & vbCrLf & server, MsgBoxStyle.Critical, "Error") channel2 = ChannelServices.GetChannel("server2") ChannelServices.UnregisterChannel(channel2) Return False Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "Error!!") channel2 = ChannelServices.GetChannel("server2") ChannelServices.UnregisterChannel(channel2) Return False End Try Return True End Function
已尝试的解决方案
- 继承原类创建第二个Collection类
- 创建全新DLL并重命名所有方法、函数与类
- 若将
remoteServer2实例化为Connection,客户端会读取第一台服务器的原始数据库
注:代码基于.NET Framework 1.0,原逻辑可用但非最优实现。
问题定位与临时修复
已确认错误源于服务端未注册Connection2类型,目前在服务端通过配置文件标识,使用switch语句注册对应类型:
Select Case connectionNo Case "1" RemotingConfiguration.RegisterActivatedServiceType(GetType(Connection)) Case "2" RemotingConfiguration.RegisterActivatedServiceType(GetType(Connection2)) Case Else Throw New Exception("No valid connection no found") End Select
优化建议
1. 复用通道与配置,减少重复操作
- 初始化阶段一次性注册所需通道,避免每次连接都注销、重新注册,减少资源开销
- 复用
BinaryServerFormatterSinkProvider和BinaryClientFormatterSinkProvider实例,无需每次创建新对象 - 通道注销前增加非空判断,避免空引用异常:
If channel IsNot Nothing Then ChannelServices.UnregisterChannel(channel)
2. 统一服务端类型注册逻辑
- 移除硬编码的switch逻辑,改用配置文件批量注册激活类型,无需修改代码即可新增服务类型:
<configuration> <system.runtime.remoting> <application> <service> <activated type="YourNamespace.Connection, YourAssembly"/> <activated type="YourNamespace.Connection2, YourAssembly"/> </service> </application> </system.runtime.remoting> </configuration>
3. 消除冗余类定义
既然是同款服务器应用,无需创建Connection2类,可通过不同的远程激活地址区分服务器:
- 客户端注册
Connection类型时,分别指定server和server2的地址 - 服务端仅需注册一次
Connection类型,通过服务端配置或上下文区分不同数据库连接,实现多实例对应不同数据源
4. 优化错误处理
- 不要忽略
RegisterActivatedClientType的异常,至少添加日志记录,便于排查注册失败问题 - 统一错误处理逻辑,避免重复编写通道注销代码,可封装成通用方法
5. 长期技术迁移建议
.NET Remoting已被微软标记为过时技术,建议逐步迁移至更现代的技术栈:
- WCF:适合.NET Framework生态下的企业级服务场景
- gRPC:跨平台、高性能,支持现代.NET(Core/.NET 5+)
- RESTful HTTP API:兼容性强,易于集成各类客户端
内容的提问来源于stack exchange,提问作者KevinC
相关产品推荐
相关产品推荐

