首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果从不同的线程调用,ResponseStream和RequestStream将永远不会继续

如果从不同的线程调用,ResponseStream和RequestStream将永远不会继续
EN

Stack Overflow用户
提问于 2018-02-03 07:58:39
回答 1查看 1.8K关注 0票数 1

Chat示例(.Net Framework4.x)包括交错读取和写入相同AsyncDuplexStreamingCall的代码。我更改了RPC示例,以包含一个流.Net:

代码语言:javascript
复制
service GreetingService {
    rpc Greeting(HelloRequest) returns (HelloResponse);
    rpc StreamGreeting(stream HelloRequest) returns (stream HelloResponse);
}

然后,我基本上复制了服务器的echo实现:

代码语言:javascript
复制
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.");
}

最后,我尝试从不同的线程读写这个流:

代码语言:javascript
复制
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从不返回/继续。在主任务/线程上运行任何一个都不能解决问题。在主任务/线程上运行两者都可以工作,包括所有形式的交叉调用。

我是不是做错了什么,或者这是一个限制?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-05 23:20:11

我可以重现您所描述的结果,但只有在发出处理线程后立即包含GreeterClient示例中的channel.ShutdownAsync().Wait()行时才能重现。

这随后会导致InvalidOperationException,因为客户端存根在流调用过程中被关闭。

为了确保所有四个调用都在服务器上处理,您需要等待所有流请求和响应完成后才能关闭:

代码语言:javascript
复制
  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();   
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48592544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档