Foreach thread.join, не работает, как ожидалось, как исправить? - PullRequest
2 голосов
/ 08 мая 2019

Я хочу запустить какой-нибудь метод в нескольких потоках, этот метод принимает аргумент. Когда я пытаюсь выполнить это, мой тест не проходит, потому что какой-то поток не работает до конца. Но в конце функции я использую Foreach { thread.join } Вот мой код: (Paths - список некоторых объектов. Parse - метод с использованием obj из Paths.)

public void RunAsync()
{
    Thread[] threadArr = new Thread[Paths.Count];
    var pathsArr = Paths.ToArray();

    for (int i = 0; i < PathsArr.Length; i++)
    {
        threadArr[i] = new Thread(new ParameterizedThreadStart(Parse));
        threadArr[i].Start((PathsArr[i]));
    }

    foreach (var thread in threadArr)
    {
        thread.Join();
    }
}

Как я могу это исправить или какую конструкцию / технику нужно использовать в этом случае? Я хочу сделать это в несколько потоков, потому что делать это синхронно слишком долго.

1 Ответ

0 голосов
/ 08 мая 2019

Thread.Join() заблокирует вам текущую тему. Это означает, что каждый цикл foreach будет выполняться после последнего запуска.

Я думаю, что вы хотите Start() ваши потоки, чтобы выполнять их параллельно.

Вот пример:

// Example-Work-Method
public static void MyAction(int waitSecs)
{
    Console.WriteLine("Starting MyAction " + waitSecs);
    Thread.Sleep(waitSecs * 1000);
    Console.WriteLine("End MyAction " + waitSecs);
}

public static void Main(string[] args)
{
    // We create a bunch of actions which we want to executte parallel
    Action[] actions = new Action[]
        {
            new Action(() => MyAction(1)),
            new Action(() => MyAction(2)),
            new Action(() => MyAction(3)),
            new Action(() => MyAction(4)),
            new Action(() => MyAction(5)),
            new Action(() => MyAction(6)),
            new Action(() => MyAction(7)),
            new Action(() => MyAction(8)),
            new Action(() => MyAction(9)),
            new Action(() => MyAction(10)),
        };

    // create a thread for each action
    Thread[] threads = actions.Select(s => new Thread(() => s.Invoke())).ToArray();

    // Start all threads
    foreach (Thread t in threads)
    {
        t.Start();
    }
    // This will "instantly" outputted after start. It won't if we'd use Join()
    Console.WriteLine("All threads are running..");

    // And now let's wait for the work to be done.
    while (threads.Any(t => t.ThreadState != ThreadState.Stopped))
        Thread.Sleep(100);

    Console.WriteLine("Done..");
}

Возможно, вам следует спросить себя, хотите ли вы вызвать этот метод Async. Асинхронные методы в c # приносят некоторые другие механизмы. Посмотрите на это: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/async

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...