C# Azure函数响应中的流式处理输出

C# Azure函数响应中的流式处理输出,c#,.net,C#,.net,我有一个正常工作的HTTP触发器函数,它启动了一个新的进程。我想做的是获取标准错误/输出并将其发送到web客户端,但我还没有找到流程处理和流式处理的正确组合,以使其正常工作 通常,一切都在运行,但似乎没有输出发送到客户端。如果可能的话,我想刷新每一行,虽然我知道网络服务器可能会阻止。目前,我正在通过AF webjob主机进行本地测试。我猜这与对象的生命周期有关,或者这是不可能的 我尝试过各种方法,但这是我目前拥有的代码,它运行并成功完成了流程,输出被记录下来,但没有输出使它成为Postman,甚

我有一个正常工作的HTTP触发器函数,它启动了一个新的进程。我想做的是获取标准错误/输出并将其发送到web客户端,但我还没有找到流程处理和流式处理的正确组合,以使其正常工作

通常,一切都在运行,但似乎没有输出发送到客户端。如果可能的话,我想刷新每一行,虽然我知道网络服务器可能会阻止。目前,我正在通过AF webjob主机进行本地测试。我猜这与对象的生命周期有关,或者这是不可能的

我尝试过各种方法,但这是我目前拥有的代码,它运行并成功完成了流程,输出被记录下来,但没有输出使它成为Postman,甚至200 OK:

[FunctionName("Function1")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req,
    CancellationToken cancellationToken,
    TraceWriter log
)
{
    using (var memoryStream = new MemoryStream())
    using (var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8, 1, true))
    //using (var streamWriter = new StreamWriter(memoryStream))
    {
        streamWriter.WriteLine($"Starting execution.");

        using (var proc = new Process())
        {
            proc.StartInfo.FileName = @"D:\Runner.exe";
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.StartInfo.UseShellExecute = false;
            //proc.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
            //{
            //    log.Info(e.Data);
            //    streamWriter.WriteLine(e.Data);
            //};
            //proc.ErrorDataReceived += (object sender, DataReceivedEventArgs e) =>
            //{
            //    log.Error(e.Data);
            //    streamWriter.WriteLine(e.Data);
            //};
            proc.Start();

            /// Need to drain the output otherwise the process will
            /// hang and not stop until the computer is shut down.
            /// It can be killed by Administrator but will remain as
            /// a process until restarted.
            /// taskkill /f /im runner.exe
            /// tasklist /fi "imagename eq runner.exe"
            while (!proc.StandardOutput.EndOfStream)
            {
                log.Info(proc.StandardOutput.ReadLine());
                streamWriter.Flush();
            }

            //proc.WaitForExit();
            streamWriter.Flush();

            var response = new HttpResponseMessage
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StreamContent(memoryStream)
            };

            return response;
        }
    }
}

我的例子比问题要新一点,但这里是如何做到的

我没有runner.exe,我认为使用CliWrap比使用System.Diagnostics.Process要好得多。我曾尝试使用不需要同步IO的解决方案,但如果确实需要执行需要同步IO的操作,则可以在函数宿主环境变量中设置函数\u V2\u兼容性\u MODE:true以使其正常工作

使用制度; 使用System.IO; Net系统; 使用System.Net.Http; 使用System.Threading.Tasks; 使用Microsoft.Azure.WebJobs; 使用Microsoft.Azure.WebJobs.Extensions.Http; 使用CliWrap; 名称空间AdamCoulter { 公共静态类精简 { [FunctionNameStreamBack] 公共静态HttpResponseMessage运行 [HttpTriggerAuthorizationLevel.Anonymous,get]HttpRequestMessage请求 { var响应=新的HttpResponseMessage { RequestMessage=请求, 内容=新PushStreamContentnew FuncRunTerraform,文本/事件流 }; response.Headers.transferncodingchunked=true; 返回响应; } 公共静态异步任务RunTerraformStream、HttpContent内容、TransportContext上下文 { _=等待Cli.WrapterForm .用英语怎么说 .WithWorkingDirectory/Volumes/Code/tftest/ .具有标准输出PipeTarget.ToStream .ExecuteAsync; 关闭;; } } } 生成终端输出时,chrome中的增量流式输出逐位显示:


[0m[1mInitializing the backend...[0m

[0m[1mInitializing provider plugins...[0m
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.58.0

[0m[1m[32mTerraform has been successfully initialized![0m[32m[0m
[0m[32m
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.[0m

我发现一件奇怪的事情是,虽然上面的代码有效,但如果我使用StandardError ReadLine、Read、EndOfStream、Peek等进行任何操作,整个过程都会冻结、超时并挂起……您是否能够将此代码作为控制台应用程序在本地工作?

[0m[1mInitializing the backend...[0m

[0m[1mInitializing provider plugins...[0m
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.58.0

[0m[1m[32mTerraform has been successfully initialized![0m[32m[0m
[0m[32m
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.[0m