C# 到 F# 和相互依赖的函数

C# to F# and Interdependent Functions

如果有人好心帮我把它翻译成 F#,我将不胜感激。当然不是 class 形式:1)如果我首先声明 ThreadProc,ThreadProc 应该使用 thread1 和 thread2,它们稍后在构造函数中使用 ThreadProc 在 main 中定义;如果我先声明 main,初始化将使用一个尚未定义的函数。 2) 如果我在定义函数 ThreadProc 之前声明了顶级 thread1 和 thread2(例如,让 thread1 = new Thread(fun () -> ())),那么这就是 ThreadProc 最终将使用的版本,而不是后来声明的版本在主要。

using System;
using System.Threading;

public class Example
{
    static Thread thread1, thread2;

    public static void Main()
    {
        thread1 = new Thread(ThreadProc);
        thread1.Name = "Thread1";
        thread1.Start();

        thread2 = new Thread(ThreadProc);
        thread2.Name = "Thread2";
        thread2.Start();   
    }   

    private static void ThreadProc()
    {
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        if (Thread.CurrentThread.Name == "Thread1" && 
            thread2.ThreadState != ThreadState.Unstarted)
                thread2.Join();

        Thread.Sleep(4000);
        Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
        Console.WriteLine("Thread1: {0}", thread1.ThreadState);
        Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
   }
}

我想出了下面的代码。但是,我将不胜感激任何让它变得更好的建议,即 smarter/shorter 方式 and/or 以某种方式不使用 'mutable' 值:

open System
open System.Threading

let mutable thread1 = new Thread( fun () -> () )
let mutable thread2 = new Thread( fun () -> () )

let threadProc () =
    printfn "\n\nCurrent Thread: %s" Thread.CurrentThread.Name

    if ( Thread.CurrentThread.Name = "Thread 1" && 
         thread2.ThreadState <> ThreadState.Unstarted ) then 
             thread2.Join ();

    Thread.Sleep(4000)
    Console.WriteLine( "\n\nCurrent thread: {0}", 
                        Thread.CurrentThread.Name )
    Console.WriteLine("Thread 1: {0}", thread1.ThreadState)
    Console.WriteLine("Thread 2: {0}\n", thread2.ThreadState)

thread1 <- new Thread(threadProc)
thread1.Name <- "Thread 1"

thread2 <- new Thread(threadProc)
thread2.Name <- "Thread 2"

let main () = 
    thread1.Start()
    thread2.Start()
    System.Console.ReadKey () |> ignore

do main () 

这证明了我在评论中所指的内容。它使用 ParameterizedThreadStart 通过 F# 记录将信息传递给线程。

您有责任确保传入的对象与线程过程中预期的类型相同。线程 proc 的参数必须是 obj 类型,因此编译器无法为您检查类型。但是为了方便,您可以在过程中使用 let args = args :?> Args 创建适当类型的 args 影子。

open System
open System.Threading

type Args = { Thread1: Thread; Thread2: Thread }

let threadProc (args: obj) =
    let args = args :?> Args

    printfn "\n\nCurrent Thread: %s" Thread.CurrentThread.Name

    if Thread.CurrentThread.Name = "Thread 1" && args.Thread2.ThreadState <> ThreadState.Unstarted then
        args.Thread2.Join ()

    Thread.Sleep(4000)
    Console.WriteLine( "\n\nCurrent thread: {0}", Thread.CurrentThread.Name )
    Console.WriteLine("Thread 1: {0}", args.Thread1.ThreadState)
    Console.WriteLine("Thread 2: {0}\n", args.Thread2.ThreadState)

let thread1 = new Thread(ParameterizedThreadStart(threadProc))
thread1.Name <- "Thread 1"

let thread2 = new Thread(ParameterizedThreadStart(threadProc))
thread2.Name <- "Thread 2"

let main () =
    let args = { Thread1 = thread1; Thread2 = thread2 }
    thread1.Start(args)
    thread2.Start(args)
    System.Console.ReadKey () |> ignore

do main ()