Я был бы признателен, если бы кто-то любезно помог мне с переводом этого на F #. Конечно, не в форме класса: 1) Если я сначала объявлю ThreadProc, предполагается, что ThreadProc будет использовать thread1 и thread2, которые позже будут определены в основном с использованием ThreadProc в конструкторах; и если я сначала объявлю main, инициализация будет использовать функцию, которая еще не определена. 2) Если я объявлю thread1 и thread2 верхнего уровня перед определением функции ThreadProc (например, пусть 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);
   }
}
0
Sasha Babaei 24 Апр 2017 в 20:07

2 ответа

Лучший ответ

Это демонстрирует то, что я имел в виду в своем комментарии. Он использует ParameterizedThreadStart для передачи информации потокам через запись F #.

Вы несете ответственность за то, чтобы убедиться, что передаваемый объект имеет тот же тип, что и ожидаемый в потоке proc. Аргумент для потока proc обязательно имеет тип obj, поэтому компилятор не может проверить тип за вас. Но вы можете создать подходящую тень args с помощью let 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 ()
1
Bent Tranberg 26 Апр 2017 в 18:36

Я придумал следующий код. Тем не менее, я был бы признателен за любые предложения по его улучшению, т. Е. Более умный / короткий путь и / или как-то не используя 'изменяемые' значения:

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 () 
0
Sasha Babaei 24 Апр 2017 в 18:00