You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建第二个.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 01:59:52