与Windows命名管道(.Net)的异步双向通信

时间:2013-05-08 04:42:42

标签: c# .net windows asynchronous named-pipes

我有一个需要相互通信的Windows服务和GUI。任何一个都可以随时发送消息。

我正在使用NamedPipes,但似乎你无法阅读&同时写入流(或者至少我找不到涵盖这种情况的任何例子)。

是否可以通过一个NamedPipe进行这种双向通信? 或者我是否需要打开两个管道(一个来自GUI->服务,一个来自service-> GUI)?

3 个答案:

答案 0 :(得分:27)

使用WCF,您可以使用双工命名管道

// Create a contract that can be used as a callback
public interface IMyCallbackService
{
    [OperationContract(IsOneWay = true)]
    void NotifyClient();
}

// Define your service contract and specify the callback contract
[ServiceContract(CallbackContract = typeof(IMyCallbackService))]
public interface ISimpleService
{
    [OperationContract]
    string ProcessData();
}

实施服务

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class SimpleService : ISimpleService
{
    public string ProcessData()
    {
        // Get a handle to the call back channel
        var callback = OperationContext.Current.GetCallbackChannel<IMyCallbackService>();

        callback.NotifyClient();
        return DateTime.Now.ToString();
    }
}

托管服务

class Server
{
    static void Main(string[] args)
    {
        // Create a service host with an named pipe endpoint
        using (var host = new ServiceHost(typeof(SimpleService), new Uri("net.pipe://localhost")))
        {
            host.AddServiceEndpoint(typeof(ISimpleService), new NetNamedPipeBinding(), "SimpleService");
            host.Open();

            Console.WriteLine("Simple Service Running...");
            Console.ReadLine();

            host.Close();
        }
    }
}

创建客户端应用程序,在此示例中,Client类实现回调合同。

class Client : IMyCallbackService
{
    static void Main(string[] args)
    {
        new Client().Run();
    }

    public void Run()
    {
        // Consume the service
        var factory = new DuplexChannelFactory<ISimpleService>(new InstanceContext(this), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/SimpleService"));
        var proxy = factory.CreateChannel();

        Console.WriteLine(proxy.ProcessData());
    }

    public void NotifyClient()
    {
        Console.WriteLine("Notification from Server");
    }
}

答案 1 :(得分:2)

您的命名管道流类(服务器或客户端)必须使用InOut的PipeDirection构造。您需要一个NamedPipeServerStream,可能在您的服务中,可以由任意数量的NamedPipeClientStream对象共享。使用管道名称和方向构造NamedPipeServerStream,使用管道名称,服务器名称和PipeDirection构造NamedPipeClientStream,您应该很高兴。

答案 2 :(得分:2)

使用单个点来累积消息(在这种情况下是单个管道)会强制您自己处理消息的方向(除此之外,您必须对管道使用系统范围的锁定。)

因此请使用方向相反的2根管道。

(另一种选择是使用2个MSMQ队列)。