首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >grpc-dotnet服务器本地进程输出流

grpc-dotnet服务器本地进程输出流
EN

Stack Overflow用户
提问于 2020-06-08 05:24:43
回答 1查看 157关注 0票数 0

我在grpc-dotnet 3.1中为一个项目工作。在服务器端,grpc调用将执行本地系统进程(例如二进制文件或脚本)。我遇到的问题是通过grpc客户端将来自进程的重定向输出进行流式处理。我现在得到的只是第一行输出。这是我的测试代码。

代码语言:javascript
复制
public override async Task ExecuteProcess(ProcessRequest request, IServerStreamWriter<ProcessReply> responseStream, ServerCallContext context)
    {
        _logger.LogInformation($"Received Execution request for {request.Name}");
        _logger.LogInformation($"Received Args {request.Args}");
        using (var process = new Process())
        {
            process.StartInfo.FileName = @"cmd.exe";
            process.StartInfo.Arguments = @"/c dir";      // print the current working directory information
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            //process.OutputDataReceived += async(sender, e) => await responseStream.WriteAsync(new ProcessReply { Message = e.Data });
            process.OutputDataReceived += (sender, e) => ShowOutput(e.Data, responseStream)
            process.Start();
            process.BeginOutputReadLine();
            //process.BeginErrorReadLine();
            var exited = process.WaitForExit(1000 * 10);     // (optional) wait up to 10 second
        }
        //return Task.FromResult(new ProcessReply { Message = "Executed " + request.Name });
        await responseStream.WriteAsync(new ProcessReply
        {
            Message = "Process Complete"
        });
    }

    private async Task ShowOutput(string data, IServerStreamWriter<ProcessReply> responseStream)
    {
        if (data != null)
        {
            _logger.LogInformation($"Process Output {data}");
            await responseStream.WriteAsync(new ProcessReply { Message = data });

        }
    }

在客户端,我只是使用流服务器示例代码来读取流中的行。

代码语言:javascript
复制
await foreach (var message in call.ResponseStream.ReadAllAsync())
{
     Console.WriteLine("Server Out: " + message.Message);
}

你知道为什么我只能从重定向的进程输出中得到一行进程输出吗?我也只看到了记录器输出中的一行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-09 00:34:31

这可能是因为您正在从事件处理程序写入ResponseStream,该事件处理程序不一定会在流的正确异步上下文中被调用。

看看CliWrap,它将整个流程执行过程包装在一个非常好的应用程序接口中,其中包括一个ListenAsync方法,它返回一个IAsyncEnumerable,您可以对其进行await foreach覆盖,并将输出写入流。

借用README,它看起来像这样:

代码语言:javascript
复制
var cmd = Cli.Wrap("cmd.exe").WithArguments("/c dir");

await foreach (var cmdEvent in cmd.ListenAsync())
{
    switch (cmdEvent)
    {
        case StandardOutputCommandEvent stdOut:
            await responseStream.WriteAsync(new ProcessReply { Message = stdOut.Text });
            break;
    }
}

await responseStream.WriteAsync(new ProcessReply { Message = "Process Complete" });
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62251866

复制
相关文章

相似问题

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