Как подождать пока выполнится поток?

У меня есть класс Dispatcher :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// using System.Windows.Threading;
using System;
using System.Windows;
public interface IDispatcher
{
    void Invoke(Action fn);
}
public class Dispatcher : IDispatcher
{
    public List<Action> pending = new List<Action>();
    private static Dispatcher instance;
    public void Invoke(Action fn)
    {
        lock (pending)
        {
            pending.Add(fn);
        }
    }
    public void InvokePending()
    {
        lock (pending)
        {
            foreach (var action in pending)
            {
                action();
            }
            pending.Clear();
        }
    }
    public static Dispatcher Instance
    {
        get
        {
            if (instance == null)
            {
                // Instance singleton on first use.
                instance = new Dispatcher();
            }
            return instance;
        }
    }
}

Я хочу дождаться завершения метода, который я запускаю с помощью Dispatcher :

Dispatcher.Instance.Invoke(() =>
{
    tempСoordinatesListVector3 = randomPointsInPolygon(brushsize, tempСoordinatesListVector3);
    foreach (var coordinat in tempСoordinatesListVector3)
    {
        Debug.Log("randomPointsInPolygon" + coordinat);
    }
    processBool = true;
});

Пока я жду так :

Dispatcher.Instance.Invoke(() =>
{
    tempСoordinatesListVector3 = randomPointsInPolygon(brushsize, tempСoordinatesListVector3);
    foreach (var coordinat in tempСoordinatesListVector3)
    {
        Debug.Log("randomPointsInPolygon" + coordinat);
    }
    processBool = true;
});


while (processBool == false)
{
    if (processBool == false) { processBool = processProgressBar(); } else { processBool = true; }
    Debug.Log("111.3");
}
processBool = false;
Debug.Log("111.3");

Но это костыль, который даже не всегда работает. От переменной processBool зависит будет ли дальше выполнятся приложение. Как переписать класс Dispatcher, чтобы он возвращал IAsyncResult и ждал BackgroundDispatcher.EndInvoke(IAsyncResult).


Ответы (1 шт):

Автор решения: Bulson

Я не работал в юнити, но вот вам простой пример

        //получаем контекст синхронизации
        var uiContext = SynchronizationContext.Current;

        Task.Run(() =>
        {
            //что-то делаем в дочернем потоке...
            //например находим файлы картинок и находим наибольший по размеру файл
            string pictures = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            var folder = new DirectoryInfo(pictures);
            FileInfo[] allFiles = folder.GetFiles("*.jpg", SearchOption.AllDirectories);
            FileInfo largest = allFiles.OrderByDescending(f => f.Length).FirstOrDefault();

            //когда нашли наибольший, надо вывести в основной поток
            //данные по размеру
            //используем для этого контекст синхронизации
            uiContext.Post(_ =>
            { 

                long sizeMB = largest.Length / (1024 * 1024);
                //здесь в текстбокс окна программы выводим размер файла
                outputTextBox.Text = $"Largest file ({sizeMB}MB) is {largest.FullName}";
            }, null);
        });
→ Ссылка