Chat示例(.Net Framework4.x)包括交错读取和写入相同AsyncDuplexStreamingCall的代码。我更改了RPC示例,以包含一个流.Net:
service GreetingService {
rpc Greeting(HelloRequest) returns (HelloResponse);
rpc StreamGreeting(stream HelloRequest) returns (stream HelloResponse);
}然后,我基本上复制了服务器的echo实现:
public override async Task StreamGreeting(/* ... */)
{
while (await requestStream.MoveNext(CancellationToken.None))
{
var request = requestStream.Current;
Console.WriteLine($"Stream Message: {request.Name}");
await responseStream.WriteAsync(new HelloResponse { Greeting = "Stream Hello " + request.Name });
}
Console.WriteLine("Stream completed.");
}最后,我尝试从不同的线程读写这个流:
var callResult = client.StreamGreeting(new CallOptions());
// Or: Task.Run
new Thread(async () =>
{
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.CompleteAsync();
}).Start();
new Thread(async () =>
{
while (await callResult.ResponseStream.MoveNext(CancellationToken.None))
{
Console.WriteLine(callResult.ResponseStream.Current.Greeting);
}
}).Start();对WriteAsync的第一次调用成功(服务器记录它收到了消息),但第二次调用永远不会返回/继续。ResponseStream.MoveNext从不返回/继续。在主任务/线程上运行任何一个都不能解决问题。在主任务/线程上运行两者都可以工作,包括所有形式的交叉调用。
我是不是做错了什么,或者这是一个限制?
发布于 2018-02-05 23:20:11
我可以重现您所描述的结果,但只有在发出处理线程后立即包含GreeterClient示例中的channel.ShutdownAsync().Wait()行时才能重现。
这随后会导致InvalidOperationException,因为客户端存根在流调用过程中被关闭。
为了确保所有四个调用都在服务器上处理,您需要等待所有流请求和响应完成后才能关闭:
var callResult = client.StreamGreeting(new CallOptions());
Task.WhenAll(new[]
{
Task.Run(async () =>
{
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.WriteAsync(request);
await callResult.RequestStream.CompleteAsync();
}),
Task.Run(async () =>
{
while (await callResult.ResponseStream.MoveNext(CancellationToken.None))
{
Console.WriteLine(callResult.ResponseStream.Current.Greeting);
}
})
}).Wait(); https://stackoverflow.com/questions/48592544
复制相似问题