How to call bursted IJob.Run() from managed C# thread?

Hi everyone

I’m trying to adjust plugin from the Asset Store to improve performance. This plugin uses default C# managed threads for better UX so that Editor doesn’t freeze while data is generating.

I found bottlenecks in the generation process and want to replace them with burst compiled code.

But I cannot run burst compiled code from C# managed thread.
When I’m running this code from thread:

var job = new MyCustomJob(){ ... }; // this is just IJob
job.Run();

I’m getting this error:
UnityException: CreateJobReflectionData can only be called from the main thread.

Sadly, calling job.Execute(); runs non-bursted job which is even worse than plain C# implementation.

I can’t use FunctionPointers because I’m heavily using NativeArrays which are forbidden with FunctionPointers.
For the same reason I can’t use this approach from Burst docs:
https://docs.unity3d.com/Packages/com.unity.burst@1.7/manual/docs/CSharpLanguageSupport_Lang.html#directly-calling-burst-compiled-code

I’m not trying to do something fancy, just to run(not schedule or smth tricky) burst compiled code from a managed thread. And I don’t mind wrapping code with Jobs to be able to use NativeArrays, but this just doesn’t work.

Any help or suggestions, please?

You “can” use native arrays together with directly calling burst compiled code, it’s just that it might be smart to wrap it. Here’s an example:

[BurstCompile]
public static class MyBurstWrapper
{
        // Nice safe interface that others call
        public static unsafe int Sum(NativeArray<int> values)
        {
            Sum((int*)values.GetUnsafePtr(), values.Length, out var result);
            return result;
        }

        // Burst compiled implementation using pointers.
        [BurstCompile]
        private static unsafe void Sum(int* values, int count, out int result)
        {
            var res = 0;
            for (int i = 0; i < count; i++)
                res += values[i];
            result = res;
        }
}

Other parts of the Collections package (if you use that) also gives access to the underlying implementation (like NativeList.GetUnsafeList) which you can send to burst functions as pointers.

1 Like