Есть ли лучший способ написать именованные каналы в F #? - PullRequest
3 голосов
/ 23 апреля 2010

Я новичок в F #. Я пытаюсь общаться с Java из F #, используя именованный канал. Приведенный ниже код работает, но я не уверен, есть ли лучший способ сделать это (я знаю, что бесконечный цикл - плохая идея, но это всего лишь подтверждение концепции), если у кого-то есть идеи по улучшению этого кода, пожалуйста, оставьте свои комментарии .

Заранее спасибо Sudaly

open System.IO
open System.IO.Pipes
exception OuterError of string


let continueLooping = true
while continueLooping do
    let pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4)
    printfn "[F#] NamedPipeServerStream thread created."

    //wait for connection
    printfn "[F#] Wait for a client to connect"
    pipeServer.WaitForConnection()

    printfn "[F#] Client connected."
    try
        // Stream for the request. 
        let sr = new StreamReader(pipeServer)
        // Stream for the response. 
        let sw = new StreamWriter(pipeServer)
        sw.AutoFlush <- true;

        // Read request from the stream. 
        let echo = sr.ReadLine();

        printfn "[F#] Request message: %s" echo

        // Write response to the stream.
        sw.WriteLine("[F#]: " + echo)

        pipeServer.Disconnect()

    with
    | OuterError(str) -> printfn "[F#]ERROR: %s" str

    printfn "[F#] Client Closing."
    pipeServer.Close()

Ответы [ 2 ]

2 голосов
/ 24 апреля 2010

Ниже вы можете найти несколько модификаций вашего кода. Ваш вопрос довольно расплывчатый, поэтому я не могу точно сказать, где вы хотите улучшить свой код, но мое предложение использует рекурсию вместо цикла while (не беспокойтесь о переполнении стека, F # может очень хорошо справляться с рекурсией и в целом рекурсивный бит будет оптимизирован в цикл во время компиляции), использует ключевое слово use (как в C #) и поглотит любое исключение, возникающее в процессе связи с клиентом. В случае возникновения исключения сервер не будет прослушивать другие соединения.

open System.IO
open System.IO.Pipes

let main() =
    printfn "[F#] NamedPipeServerStream thread created."
    let pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4)
    let rec loop() =
        //wait for connection
        printfn "[F#] Wait for a client to connect"
        pipeServer.WaitForConnection()

        printfn "[F#] Client connected."
        try
            // Stream for the request. 
            use sr = new StreamReader(pipeServer)
            // Stream for the response. 
            use sw = new StreamWriter(pipeServer, AutoFlush = true)

            // Read request from the stream. 
            let echo = sr.ReadLine();

            printfn "[F#] Request message: %s" echo

            // Write response to the stream.
            echo |> sprintf "[F#]: %s" |> sw.WriteLine

            pipeServer.Disconnect()
            if [A CONDITION WHICH TELLS YOU THAT YOU WANT ANOTHER CONNECTION FROM THE CLIENT] then loop()
        with
        | _ as e -> printfn "[F#]ERROR: %s" e.Message
    loop()
    printfn "[F#] Client Closing."
    pipeServer.Close()

Также обратите внимание, как AutoFlush устанавливается в вызове конструктора и как оператор конвейера используется для записи эха в канал, что приводит к тому, что выглядит (на мой взгляд) как более чистый код.

2 голосов
/ 23 апреля 2010

Ну, похоже, что ничего не выбрасывает OuterError, поэтому я бы удалил этот тип исключения и неиспользуемую обработку.

Я не уверен в вашем уровне опыта или в том, какого типа «лучше» вы ищете. Вы хотите прочитать F # async на сервере , чтобы узнать больше об асинхронности и избежании блокирования потоков.

...