Reputation: 485
I would appreciate it if someone kindly helps me with translating this into F#. Not in the class form of course: 1) If I declare ThreadProc first, ThreadProc is supposed to use thread1 and thread2 which are later defined in the main using ThreadProc in the constructors; and if I declare main first, the initialisations will use a function that is not yet defined. 2) If I declare top-level thread1 and thread2 before defining function ThreadProc (e.g., let thread1 = new Thread(fun () -> ())), then that is the version that ThreadProc will ultimately utilise rather than the one later declared in the main.
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);
}
}
Upvotes: 0
Views: 149
Reputation: 3470
This demonstrates what I was referring to in my comment. It uses ParameterizedThreadStart to pass information to the threads via an F# record.
You are responsible for making sure that the object passed in is of the same type as is expected within the thread proc. The argument to the thread proc is necessarily of type obj
, so the compiler can't check the type for you. But you can create an appropriately typed shadow of args
with let args = args :?> Args
for convenience within the proc.
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 ()
Upvotes: 1
Reputation: 485
I have come up with the following code. However, I would appreciate any suggestions on making it better, i.e., the smarter/shorter way and/or somehow not-using 'mutable' values:
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 ()
Upvotes: 0