Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何重定向错误但不输出,并保持以正确的顺序将文本写入控制台?(F#)_.net_F#_System.diagnostics_Processstartinfo_Redirectstandardoutput - Fatal编程技术网

.net 如何重定向错误但不输出,并保持以正确的顺序将文本写入控制台?(F#)

.net 如何重定向错误但不输出,并保持以正确的顺序将文本写入控制台?(F#),.net,f#,system.diagnostics,processstartinfo,redirectstandardoutput,.net,F#,System.diagnostics,Processstartinfo,Redirectstandardoutput,我有两个正在运行的程序,其中一个作为子进程由另一个运行。当子进程写入stderr时,我想在父进程中捕获它,这样我就可以判断是否有错误,然后像子进程一样将错误消息记录到控制台 问题是,子进程在写入stderr之后立即将几行文本写入stdout。当父进程截获stderr消息并自己记录它们时,它们将与stdout消息并行写入,文本以错误的顺序显示 我创建了两个F#脚本,作为这个问题的最小复制。这是子进程的脚本: open System let logError (x : string) : unit

我有两个正在运行的程序,其中一个作为子进程由另一个运行。当子进程写入stderr时,我想在父进程中捕获它,这样我就可以判断是否有错误,然后像子进程一样将错误消息记录到控制台

问题是,子进程在写入stderr之后立即将几行文本写入stdout。当父进程截获stderr消息并自己记录它们时,它们将与stdout消息并行写入,文本以错误的顺序显示

我创建了两个F#脚本,作为这个问题的最小复制。这是子进程的脚本:

open System

let logError (x : string) : unit =
    Console.ForegroundColor <- ConsoleColor.Red
    try stderr.WriteLine x
    finally Console.ResetColor ()

let logWarning (x : string) : unit =
    Console.ForegroundColor <- ConsoleColor.Yellow
    try stdout.WriteLine x
    finally Console.ResetColor ()

let logInfo (x : string) : unit =
    Console.ForegroundColor <- ConsoleColor.Green
    try stdout.WriteLine x
    finally Console.ResetColor ()

logError "The quick brown fox jumps over the lazy dog."

logWarning "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc eu est ut arcu finibus iaculis. Maecenas dapibus luctus convallis. Donec tristique accumsan ante sit amet maximus. Sed molestie eros sit amet pretium rhoncus. Sed odio lectus, vestibulum vitae consequat sit amet, eleifend ac augue. Vivamus eros quam, lobortis eget consequat in, pulvinar vel dolor. Sed efficitur fermentum purus eu imperdiet. Mauris posuere, metus nec fringilla accumsan, massa nisi egestas augue, et tristique ligula dolor sit amet nibh. Proin ultricies fermentum tellus, vitae porttitor mauris elementum id. Donec arcu dolor, posuere vel efficitur ultrices, sollicitudin sit amet mauris. Sed eu suscipit leo, in vehicula sem. Morbi congue nibh vitae orci lobortis, gravida volutpat augue imperdiet. Phasellus fringilla arcu ac tellus porttitor mattis. Donec in ante vitae sem varius pulvinar."

logInfo "Nam lorem justo, laoreet ac convallis et, semper et leo. Fusce ornare, risus ut porta tristique, purus lacus ultricies ante, ac semper metus eros quis sapien. Nunc vulputate neque ut efficitur condimentum. Quisque facilisis lacus at lorem condimentum suscipit. Aenean volutpat et dui non pharetra. Pellentesque pretium euismod sollicitudin. Phasellus ullamcorper nulla quis nibh tincidunt consectetur. Nulla gravida finibus mi, sed elementum ligula maximus sed. Ut eu dignissim ex. Nullam vestibulum accumsan ex, ut facilisis elit facilisis scelerisque. Integer pellentesque, sem a molestie porta, tortor felis consectetur lorem, ut interdum lacus mauris vel nisi. Maecenas justo nulla, pharetra at malesuada ac, sollicitudin quis tortor. Integer vehicula, mauris ac tristique vehicula, leo nibh cursus sem, sed rhoncus libero sapien ac tellus."
开放系统
let logError(x:string):单位=

Console.ForegroundColor父进程了解子进程是否有错误的典型方法是当退出代码不同于零时使用退出代码。除此之外,您还需要一些其他类型的进程间通信

我知道您说过锁不起作用,但为了以防万一,我将为您提供这个可能的解决方案,该解决方案适用于您发布的特定场景:

这包括使用
MailBoxProcessor
对操作进行排序。首先是一些辅助函数:

module Mailbox =

    /// A simple Mailbox processor to serially process Async tasks
    /// use:
    ///      let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
    ///      logThisMsgA.Post "message Async"
    ///      
    let iterA hndl f =
        MailboxProcessor.Start(fun inbox ->
            async {
                while true do
                    try       let!   msg = inbox.Receive()
                              do!  f msg
                    with e -> hndl e
            }
        )

    /// A simple Mailbox processor to serially process tasks
    /// use:
    ///      let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
    ///      logThisMsg.Post "message"
    ///      
    let iter hndl f = iterA hndl (fun msg -> async { f msg } )
以下是邮箱代理和调用它的函数:

let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
let logSeq    f txt = sequenceActions.Post <| fun () -> f txt

我希望这能有所帮助。

父进程了解子进程是否有错误的典型方法是当退出代码不同于零时使用退出代码。除此之外,您还需要一些其他类型的进程间通信

我知道您说过锁不起作用,但为了以防万一,我将为您提供这个可能的解决方案,该解决方案适用于您发布的特定场景:

这包括使用
MailBoxProcessor
对操作进行排序。首先是一些辅助函数:

module Mailbox =

    /// A simple Mailbox processor to serially process Async tasks
    /// use:
    ///      let logThisMsgA = Mailbox.iterA (printfn "%A") (fun msg -> async { printfn "Log: %s" msg } )
    ///      logThisMsgA.Post "message Async"
    ///      
    let iterA hndl f =
        MailboxProcessor.Start(fun inbox ->
            async {
                while true do
                    try       let!   msg = inbox.Receive()
                              do!  f msg
                    with e -> hndl e
            }
        )

    /// A simple Mailbox processor to serially process tasks
    /// use:
    ///      let logThisMsg = Mailbox.iter (printfn "%A") (printfn "Log: %s")
    ///      logThisMsg.Post "message"
    ///      
    let iter hndl f = iterA hndl (fun msg -> async { f msg } )
以下是邮箱代理和调用它的函数:

let sequenceActions = Mailbox.iter (printfn "%A") (fun f -> f() )
let logSeq    f txt = sequenceActions.Post <| fun () -> f txt

我希望这有帮助。

你试过我的建议吗?这对你有用吗?@AMieres谢谢你的回答,但我认为它不会有用,因为在我的情况下,父母和孩子需要分开处理。正如你所说,除了使用退出代码或IPC之外,可能没有其他方法可以让我想要的工作正常进行,我会研究这些方法。你必须尝试一下才能确定。我想你会感到惊讶。我很好奇你是否尝试过,这是否对你有效:这些人似乎也有同样的问题:@AMieres
MailBoxProcessor
对于并发性来说似乎是一个非常好的主意。不幸的是,它不适合我的情况,因为我需要能够独立地运行子进程并将它们打印到控制台,而不是总是使用
邮箱
代理。我能针对我的特殊情况解决这个问题,但我会记住你的答案,以备将来工作之用。你试过我的建议了吗?这对你有用吗?@AMieres谢谢你的回答,但我认为它不会有用,因为在我的情况下,父母和孩子需要分开处理。正如你所说,除了使用退出代码或IPC之外,可能没有其他方法可以让我想要的工作正常进行,我会研究这些方法。你必须尝试一下才能确定。我想你会感到惊讶。我很好奇你是否尝试过,这是否对你有效:这些人似乎也有同样的问题:@AMieres
MailBoxProcessor
对于并发性来说似乎是一个非常好的主意。不幸的是,它不适合我的情况,因为我需要能够独立地运行子进程并将它们打印到控制台,而不是总是使用
邮箱
代理。我能够针对我的特殊情况解决这个问题,但我会记住你的答案,以备将来工作时参考。