为IPC使用WCF和NetNamedPipeBinding

为IPC使用WCF和NetNamedPipeBinding,wcf,ipc,named-pipes,timeoutexception,Wcf,Ipc,Named Pipes,Timeoutexception,我试图学习WCF,将其用作主机/插件系统的IPC机制。主机需要能够调用插件来启动/停止它,插件需要调用服务器来执行日志记录 我做了一个简单的测试用例,主机在net上创建一个端点。pipe://localhost/SampleServer与以下服务合同签订: [ServiceContract] public interface IWcfServer { [OperationContract] void Log(string message); } [ServiceContract

我试图学习WCF,将其用作主机/插件系统的IPC机制。主机需要能够调用插件来启动/停止它,插件需要调用服务器来执行日志记录

我做了一个简单的测试用例,主机在
net上创建一个端点。pipe://localhost/SampleServer
与以下服务合同签订:

[ServiceContract]
public interface IWcfServer
{
    [OperationContract]
    void Log(string message);
}
[ServiceContract]
public interface IWcfClient
{
    [OperationContract]
    string Init();
}
插件在
net上创建一个端点。pipe://localhost/SampleClient
与以下服务合同签订:

[ServiceContract]
public interface IWcfServer
{
    [OperationContract]
    void Log(string message);
}
[ServiceContract]
public interface IWcfClient
{
    [OperationContract]
    string Init();
}
下面是我如何设置每个端点的示例:

this.server = new ServiceHost(this);
this.server.AddServiceEndpoint(typeof(IWcfServer), 
                               new NetNamedPipeBinding(), 
                               "net.pipe://localhost/SampleServer");
this.server.Open();
下面是我如何打电话的示例:

ChannelFactory<IWcfClient> factory = new ChannelFactory<IWcfClient>(
                            new NetNamedPipeBinding(),
                            new EndpointAddress("net.pipe://localhost/SampleClient"));
IWcfClient client = factory.CreateChannel();
using ((IClientChannel)client)
{
    client.Init());
}
ChannelFactory工厂=新的ChannelFactory工厂(
新建NetNamedPipeBinding(),
新端点地址(“net。pipe://localhost/SampleClient"));
IWCClient=factory.CreateChannel();
使用((IClientChannel)客户端)
{
client.Init());
}
我已经确认主机可以调用
plugin.Init()
,插件可以调用
host.Log(message)
,没有问题。但是,如果发生以下情况:

  • 主机调用plugin.Init()
  • 在执行plugin.Init()期间,插件尝试调用host.Log(消息)

  • 应用程序冻结,1分钟后我得到一个
    TimeoutException
    。有人知道我做错了什么吗?

    1分钟是标准的wcf超时时间

    你有循环参考资料吗


    另外,当你打电话给正在监听的client.init时,为什么你有两份合同?

    打开WCF的E2E跟踪,以检查到底是什么超时。此外,您的方法可能会导致死锁,因为init可能需要log,而log可能需要init先发生,或者类似的事情

    服务主机的InstanceContextMode是什么?如果它是单例,它将阻塞,直到Init()返回-导致循环依赖关系。

    “net。pipe://localhost/SampleServer" “净。pipe://localhost/SampleClient"
    服务器和客户端有两个不同的URL。这是个问题

    我知道没有循环引用,因为当前的日志“实现”只是MessageBox.Show(message)。我将启用该跟踪并在明天查看。无循环引用,请参阅我对Sajay消息的评论。我有两个契约和两个不同的端点,因为主机和插件之间有两条独立的通信路径。主机实现IWcfServer并调用plugin.Init,而插件实现IWCClient并调用host.Log.It is。我发现,对于那个特定的示例,如果我添加UseSynchronizationContext=false,它会起作用,但对于真正的应用程序,我最终重写了东西,使用InstanceContextMode.PerCall.Not,它不是。这是一种双向通信,使用两个不同的管道,一个用于服务器->客户端,另一个用于客户端->服务器。因此,
    void
    -返回
    Log()
    上的不同endpoints.FYI,“IsOneWay”可能有助于避免阻塞
    [操作契约(IsOneWay=true)]
    -如中所述