Skip to main content
added 422 characters in body
Source Link

EDIT

The Jobs based answer below can work.

But for anyone who has use case I had (one expensive level generator algorithm to run in background rather than many parallel ones), just using Async/Await Tasks requires much less refactoring. This video was helpful:

https://www.youtube.com/watch?v=oWFJl56IL4Y


Original answer

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

ScheduleBatchedJobs docs

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete(); // do I need this? What does it do in this case?
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

ScheduleBatchedJobs docs

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete(); // do I need this? What does it do in this case?
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

EDIT

The Jobs based answer below can work.

But for anyone who has use case I had (one expensive level generator algorithm to run in background rather than many parallel ones), just using Async/Await Tasks requires much less refactoring. This video was helpful:

https://www.youtube.com/watch?v=oWFJl56IL4Y


Original answer

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

ScheduleBatchedJobs docs

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete(); // do I need this? What does it do in this case?
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

added 390 characters in body
Source Link

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

ScheduleBatchedJobs docs

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete(); // do I need this? What does it do in this case?
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}
 
```

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete();
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}
 
```

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

ScheduleBatchedJobs docs

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete(); // do I need this? What does it do in this case?
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

added 390 characters in body
Source Link

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete();
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

```

This seems to work

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

```

This seems to work. I didn't realise that it will launch scheduled jobs even if you don't call Complete();.

In fact the job will execute even if you don't call JobHandle.ScheduleBatchedJobs(); but the docs seem to say you should call that, so I'm assuming in more complex code there can be a condition when the job won't pick up. Perhaps I'm wrong about this.

public class JobTest : MonoBehaviour
{
    JobHandle myJob;
    bool started = false;
    bool done = false;
    void Update()
    {
        if (!started)
        {
            if (Time.realtimeSinceStartup > 5)
            {
                print("scheduling");
                myJob = scheduleLongJob();
                JobHandle.ScheduleBatchedJobs(); 
                started = true;
            }
        }

        if (myJob.IsCompleted && started)
        {
            myJob.Complete();
            print("job completed");
            done = true;
        }        
    }
    JobHandle scheduleLongJob()
    {
        LongJob myJob = new LongJob();
        return myJob.Schedule(); 
    }
}

public struct LongJob : IJob
{
    public void Execute()
    {
        float u = 0;
        for (int i = 0; i < 50000000; i++)
        {
            u += math.exp10(math.sqrt(10f));
        }
        Debug.Log(u);
    }
}

```
added 2 characters in body
Source Link
Loading
Source Link
Loading