1

A simple data contract class to be passed:

[DataContract]
public class MyData
{
    [DataMember]
    public float Value1 {get;set;}
    [DataMember]
    public float Value2 {get;set;}     
    [DataMember]   
    public float Value3 {get;set;}   
}

Server code:

var serializer = new DataContractSerializer(typeof(MyData));

using (var pipe = new NamedPipeServerStream("testpipe", PipeDirection.InOut))
{
    pipe.WaitForConnection();
    
    var data = new MyData
    {
        Value1 = 200,
        Value2 = 456,
        Value3 = 10234.33f
    };

    serializer.WriteObject(pipe, data);
}

Client code:

var serializer = new DataContractSerializer(typeof(MyData));

using (var client = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut))
{
    client.Connect();
    
    var data = (MyData)serializer.ReadObject(client);
}

The call to ReadObject above just hangs without throwing any exceptions. Using XmlSerializer is the exact same.

Can these serializers even be used directly on the named pipes streams or is one forced to use manual string/byte messages parsing?

mainvoid
  • 347
  • 1
  • 4
  • 17
  • Do these answer your question? [Named pipe hanging on read](https://stackoverflow.com/q/32297779/344280) and [C# Named pipe stream readline hangs](https://stackoverflow.com/q/48990960/344280), – dbc May 04 '21 at 17:28

1 Answers1

0

You are missing the XmlDictionaryReader which can be seen in the documentation. Also please make sure to not run the client and server class from one and the same project.

I created a console project and run server.serialize() as main application.

public class Server
{
    public void Serialize()
    {
        using var pipe = new NamedPipeServerStream("testpipe", PipeDirection.InOut);
        var serializer = new DataContractSerializer(typeof(MyData));

        pipe.WaitForConnection();

        var data = new MyData
        {
            Value1 = 200,
            Value2 = 456,
            Value3 = 10234.33f
        };

        serializer.WriteObject(pipe, data);
        
    }
}

Then I made another console project and run Client.Deserialize() as second application (right click on project->debug->Start New Instance)

public class Client
{
    public void Deserialize()
    {
        using var pipe = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut);
        var reader = XmlDictionaryReader.CreateTextReader(pipe, new XmlDictionaryReaderQuotas());
        var serializer = new DataContractSerializer(typeof(MyData));

        pipe.Connect();

        var data = serializer.ReadObject(reader);
        Console.WriteLine(data);

    }
}

It worked perfectly fine with this set up. I hoped this solves your problem. Cheers!

Edit1: Changed the answer from using FileStream to NamedPipeStreams and clarified my approach.

Patrick
  • 387
  • 3
  • 15
  • Doesn't work with a named pipe stream. The call to ReadObject with the XmlDictionaryReader parameter still hangs. – mainvoid May 04 '21 at 16:10
  • I now tried it with namedpipes and updated my answer accordingly. Let me know if this gets you any further down the road. – Patrick May 04 '21 at 18:23
  • Turns out my code didn't work because it was inside a while loop (both the WriteObject from the server and the ReadObject from the client). If I just send the object once it works. Also XmlDictionaryReader is not needed. I wonder how I can keep sending the object after having recieved a connection from the client. – mainvoid May 06 '21 at 12:21
  • 1
    I find the answer on this question very instructive, it was also made with an while loop. https://stackoverflow.com/questions/895445/system-io-exception-pipe-is-broken – Patrick May 06 '21 at 12:45
  • That question helped a lot indeed.I added a call to NamedPipeServerStream.Disconnect in the while loop and now it works! Thanks a lot for your help. I'll vote to close my question as a duplicate with the one you linked. – mainvoid May 06 '21 at 14:23