简体   繁体   English

通过IPC进行.NET远程调用时MissingMethodException

[英]MissingMethodException when making a .NET Remoting call over IPC

I have a service which needs to pump strings to a helper application which displays critical messages from the service to the user (Vista+ does not give services access to the GUI). 我有一个需要将字符串泵送到帮助程序的服务,该应用程序显示从服务到用户的关键消息(Vista +不允许服务访问GUI)。 Since I've used .NET Remoting over TCP, I figured I'd do the same with the IPC protocol. 由于我使用过TCP上的.NET Remoting,因此我想对IPC协议也可以这样做。 However, after getting the reference to the remote object, I get the following exception when making a call to the remote method: 但是,在获得对远程对象的引用之后,在调用远程方法时出现以下异常:

MissingMethodException: No parameterless constructor defined for this object.

Simply adding a parameterless constructor to the class gives me a NullReferenceException when making the call instead. 只需在类中添加无参数构造函数,即可在进行调用时获得NullReferenceException。 What is it that I am doing wrong? 我做错了什么? I've included my relevant code below: 我在下面添加了相关代码:

Application Code 申请代码

public class MyMsgBus : MarshalByRefObject, IDisposable, IMxServeBus
{
    private Thread myThread = null;
    private volatile List<string> myMsgBus = null;
    private volatile bool myThreadAlive = false;
    private volatile bool myIsDisposed = false;
    private volatile bool myIsDisposing = false;
    private IpcChannel myIpc = null;

    public MyMsgBus(string busname)
    {
       myMsgBus = new List<string>();

       myIpc = CreateIpcChannel(busname);
       ChannelServices.RegisterChannel(myIpc);

       var entry = new WellKnownServiceTypeEntry(
          typeof(MxServeBus),
          "MyRemoteObj.rem",
          WellKnownObjectMode.Singleton);

       RemotingConfiguration.RegisterWellKnownServiceType(entry);
    }

    // defined in IMyMsgBus
    public void SendMessage(string message)
    {
       // do stuff
    }

    public static IpcChannel CreateIpcChannel(string portName)
    {
       var serverSinkProvider = new BinaryServerFormatterSinkProvider();
       serverSinkProvider.TypeFilterLevel = TypeFilterLevel.Low;

       IDictionary props = new Hashtable();
       props["portName"] = portName;
       props["authorizedGroup"] = "Authenticated Users";

       return new IpcChannel(props, null, serverSinkProvider);
    }

    public static IpcChannel CreateIpcChannelWithUniquePortName()
    {
       return CreateIpcChannel(Guid.NewGuid().ToString());
    }
}

Test Client 测试客户

static void Main(string[] args)
{
   var channel = MyMsgBus.CreateIpcChannelWithUniquePortName();
   ChannelServices.RegisterChannel(channel, true);

   var objUri = "ipc://MyMsgBus/MyRemoteObj.rem";
   IMyMsgBus lBus = (IMyMsgBus)Activator.GetObject(typeof(IMyMsgBus), objUri);
   lBus.SendMessage("test");
   Console.WriteLine();
}

Thanks in advance for any assistance on this. 在此先感谢您的协助。 As an FYI, this is a remoting instance configured through the use of a shared interface, where IMyMsgBus defines the methods which should be available to call over IPC. 作为一个FYI,这是一个通过使用共享接口配置的远程处理实例,其中IMyMsgBus定义了应可用于通过IPC调用的方法。

You are getting NullReferenceException on adding parameterless constructor as parameter is required for proper initialization. 在添加无参数构造函数时,您将收到NullReferenceException ,因为正确初始化需要使用参数。 By not supplying it, some part of initialization is missed. 由于不提供它,因此缺少初始化的某些部分。

You should refactor your code to allow parameter less constructor as 您应该重构代码,以减少参数的构造函数,因为

   private bool _initialized = false;

    public MyMsgBus() {}

    public Initialize(string busname) // Make this part of interface    
    {
       myMsgBus = new List<string>();

       myIpc = CreateIpcChannel(busname);
       ChannelServices.RegisterChannel(myIpc);

       var entry = new WellKnownServiceTypeEntry(
          typeof(MxServeBus),
          "MyRemoteObj.rem",
          WellKnownObjectMode.Singleton);

       RemotingConfiguration.RegisterWellKnownServiceType(entry);
       _initialized = true;
    }

In all other public methods, check for _initialized flag and throw NotInitializedException if flag is false. 在所有其他公共方法中,检查_initialized标志,如果标志为false,则throw NotInitializedException

You should use it as 您应该将其用作

 IMyMsgBus lBus = (IMyMsgBus)Activator.GetObject(typeof(IMyMsgBus));
 lBus.Initialize(objUri);
 ... do Further operation

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM