Как использовать единство "JobSystem" без основного потока, а не заморозить? - PullRequest
0 голосов
/ 26 июня 2019

Я хочу использовать эту загрузку в фоновом режиме, но Jobsystem, вероятно, использует основной поток, так как же использовать систему заданий Wituhot Freezes, это невозможно?Или я просто использую C # Thread ??Не использовать JobSystem ??

struct SleepJob : IJobParallelFor
{
    public void Execute(int index)
    {
        Debug.LogFormat("[SleepJob.Execute] Thread Id {0}", Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1);
    }
}
struct SleepJob2 : IJobParallelFor
{
    public void Execute(int index)
    {
        Debug.LogFormat("[SleepJob2.Execute] Thread Id {0}", Thread.CurrentThread.ManagedThreadId);
        Thread.Sleep(1);
    }
}
[ContextMenu("JobSleep")]
public void JobSleep()
{
    Debug.LogFormat("[JobSleep.Execute] Thread Id {0}", Thread.CurrentThread.ManagedThreadId);

    SleepJob job = new SleepJob() { };
    SleepJob2 job2 = new SleepJob2() { };
    JobHandle jh = job.Schedule(100, 64);
    JobHandle jh2 = job2.Schedule(100, 64, jh);
    JobHandle.ScheduleBatchedJobs();
    jh2.Complete(); // freezes

    Debug.LogFormat("[JobSleep.Execute] jh.Complete();");
}

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Обратите внимание, что Complete останавливает выполнение, потому что:

JobSystem автоматически устанавливает приоритеты для задания и любых его зависимостей для запуска сначала в очереди, а затем пытаетсявыполнить само задание в потоке, который вызывает функцию Complete .

Я думаю, что это не тот метод, который вы хотите использовать.

Скорее попробуйте дождатьсязадание, которое нужно выполнить в сопрограмме , например,

[ContextMenu("JobSleep")]
public void JobSleep()
{
    Debug.LogFormat("[JobSleep.Execute] Thread Id {0}", Thread.CurrentThread.ManagedThreadId);

    SleepJob job = new SleepJob() { };
    SleepJob2 job2 = new SleepJob2() { };
    JobHandle jh = job.Schedule(100, 64);
    JobHandle jh2 = job2.Schedule(100, 64, jh);
    JobHandle.ScheduleBatchedJobs();

    StartCoroutine(WaitFor(jh2));
}

IEnumerator WaiFor(JobHandle job)
{
    yield return new WaitUntil(() => job.IsComplete);

    Debug.LogFormat("[JobSleep.Execute] job IsComplete");
}

К сожалению, вы не добавили код, который действительно хотите выполнить в фоновом режиме.

В общем, возможно, простое использование Thread или async может уже решить вашу проблему.

, например, с Thread

// for sending back responses to the main thread
private ConcurrentQueue<Action> callbacks = new ConcurrentQueue<Action>;

// work the callbacks in the main thread
private void Update()
{
    while(callbacks.Count > 0)
    {
        Action callback;
        if(callbacks.TryDequeue(out callback)) callback?.Invoke();
    }
}

// optional callback on success
public void StartBackgroundTask(Action onSuccess = null)
{
    var thread = new Thread(new ParameterizedThreadStart(TheTaskThatTakesAWhile);
    // pass in parameters here
    thread.Start(onSuccess);
}

// Will be running in a background thread
private void TheTaskThatTakesAWhile(Action onSuccess)
{
    // hand this back to the main thread
    callbacks.Enqueue(() => Debug.Log("Long task started ..."));

    // TODO whatever takes so long

    // Note btw that sleep is in milliseconds!
    Thread.Sleep(1000);

    hand this back to the mainthread
    callbacks.Enqueue(() => 
    {
        Debug.Log("Long task started ..."));

        onSuccess?.Invoke();
    }
}

например, используя async (который внутренне также выполняется в потоке)

private async Task TheTaskThatTakesAWhile()
{
    // do whatever takes long here
}

// usually you should avoid having async void
// but when including an Action as callback this is fine
public async void StartBackgroundTask(Action onSuccess = null)
{
    await TheTaskThatTakesAWhile();

    onSuccess?.Invoke();
}

Оба вы можете вызвать как, например,

StartBackgroundTask(() => {
    // what should happen when done?

    Debug.Log("I'm done!");
});
1 голос
/ 26 июня 2019

Сделать JobHandle глобальной переменной jh2.Проверьте JobHandle.isComplete в методе обновления или в сопрограмме

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