Paul Stanley
Paul Stanley

Reputation: 2161

Awaited Networkstream Signal to Send Data

I was trying to work out how to signal a Networkstream to await writeAsync when it is being awaited readasync.I was unsure of a mechanism to return from the stream.readasync method as below. I came up with a way to signal a task to complete that would allow the writing to the stream. This code seems wrong in it's approach.Would there be better approach?

    async Task SocketStuff(TcpListener listener)
    {
        TcpClient client = await listener.AcceptTcpClientAsync();
        NetworkStream stream = client.GetStream();
        var buf = new byte[2048];
        var readTask = stream.ReadAsync(buf, 0, buf.Length);
        var signalToSend = SignalReadyToSendAsync();
        var completetedTask = await Task.WhenAny(readTask, signalToSend);
        if (completetedTask == signalToSend)
        {
            await stream.WriteAsync(someData, 0, someData.Length);
        }
        if (completetedTask == readTask)
        {
            // .....
        }
    }
    async Task SignalReadyToSendAsync()
    {
        while (nothingToSend)
        {
            await Task.Delay(250);
        }
        return;

Upvotes: 1

Views: 42

Answers (2)

Paul Stanley
Paul Stanley

Reputation: 2161

I think that using one method is easy to understand but you just need to be able to get to the completed task when a msg is ready to be sent. You can do this with setting a task:

         Task msgReadyTask = Task.Delay(Timeout.Infinite, mrtToken);

mrtToken can be cancelled when a msg is ready to be sent to signal the end of that cycle.

Upvotes: 0

Nitram
Nitram

Reputation: 6716

If you want to handle the Stream fully inside a method this would be a way. But I suggest you wrap the whole thing into another class, that stores a instance of the Stream and exposes a function that directly writes it's data to the stream.

So basically you have a method:

Task SendData(byte[] data)
{
    return stream.WriteAsync(someData, 0, someData.Length);
}

This method is called from the outside, every time data needs to be send. The wrapping class should store the the stream as a class level variable.

Basically you create the class with the network stream and it starts a function automatically that receives data and processes (or forwards) it.

Handling it all inside a single method is tricky and requires support classes as you noticed that makes everything more complicated.

Upvotes: 1

Related Questions