Обратите внимание, что 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!");
});