async Streaming in C#

172 views
Skip to first unread message

Allan Zimmermann

unread,
Feb 13, 2023, 5:39:28 AM2/13/23
to grpc.io
Hey
I made a simple grpc service in nodejs
It has a function defined as

rpc SetupStream (stream Envelope) returns (stream Envelope) {}

I made a few client's in both nodejs, javascript and python that can use those streams asynchronous without any issues, but in C# the receive stream keeps getting blocked as soon as i send something from the client.
When i call my SetupStream on the stub i get back a 
AsyncDuplexStreamingCall<Envelope, Envelope>
No matter if I use ResponseStream.MoveNext or ResponseStream.ReadAllAsync it works perfectly and as soon as the server sends a message i can process it, right until i send a message using RequestStream.WriteAsync .. then i no longer receive message as the server sends them but only right after sending a  message using RequestStream.WriteAsync ( I have confirmed the server is sending and the client is receiving them, but MoveNext/ReadAllAsync just hangs for ever until WriteAsync is called again )
I want to process the messages as soon as the server sends tham, and not only after calling WriteAsync, just like i can do in node/js/python.

I feel it must be a fault on my part, but i simply cannot spot it. I've been unable to find any working examples on how to use a stream in C# except https://github.com/chgc/grpc-dotnetcore-3-chat but once i upgrade this to dotnet 6 this also fails to receive any messages.
Is Bidirectional streams supported in C# like all the other languages ? and if so, does anyone have a very basic and simple example showing how to have a thread processing incoming message as they come in while also supporting sending messages ?
Regards
Allan Zimmermann
Message has been deleted

Allan Zimmermann

unread,
Feb 13, 2023, 6:19:53 AM2/13/23
to grpc.io
Typically, i was banging my head on this for 1½ and shortly after posting this i find the error in my code.
I was adding a promise to an array, to handle responses as they come back
promises.Add(id, new TaskCompletionSource<Envelope>());
When setting the response
promises[response.Rid].SetResult(response);
caller would be running on the same thread, and stalling it
The solution was to create the promisse like this instead
promises.Add(id, new TaskCompletionSource<Envelope>(TaskCreationOptions.RunContinuationsAsynchronously));

Reply all
Reply to author
Forward
0 new messages