Lock class/struct to a single thread/worker

Background:

I am trying to implement threading for procedural mesh generation. I’ve managed to create a flat mesh with vertices, triangles, normals and uv’s on multiple seperate threads/workers in parallell using Jobs package. Here comes the difficult part however; back when I procedural generated my meshes sequentially I used this library (FastNoiseLite) and I can’t get this to run on seperate threads.

__

Question(s):

How can I lock an entire already instanciated class to a single thread/worker?

Or alternatively:

How can I instanciate a class in another thread other than the main thread?

__
Relevant Code:

public struct CreateMeshByNoiseJob : IJob
{
    [WriteOnly] public NativeArray<Vector3> vertices;

    [ReadOnly] public NativeArray<Noise.NoiseLayer> noise_layers; // This is what breaks
    [ReadOnly] public Vector3 offset;

    public void Execute()
    {
        int noise_length = noise_layers.Length;
        for (int q = 0; q < noise_length; q++)
        {
            if (noise_layers[q].enabled)
            {
                for (int i = 0; i < vertices.Length; i++)
                { 
                    // This is what breaks
                    vertices <em>= new Vector3(vertices<em>.x, vertices<em>.y + noise_layers[q].GetNoiseValue(vertices<em>.x, vertices_.z), vertices*.z);*_</em></em></em></em>

}
}
}
}
}
__
public struct NoiseLayer
{
private FastNoiseLite warp;
private FastNoiseLite noise;

public bool enabled;

private float amplitude;
private Vector2 offsett;

private float min_value;
private float smoothing_min;
private float max_value;
private float smoothing_max;

private float SmoothMin(float a)
{
float h = Mathf.Max(0f, Mathf.Min(1f, (max_value - a + smoothing_max) / (2f * smoothing_max)));
return a * h + max_value * (1f - h) - smoothing_max * h * (1f - h);
}

private float SmoothMax(float a)
{
float h = Mathf.Max(0f, Mathf.Min(1f, (min_value - a + smoothing_min) / (2f * smoothing_min)));
return a * h + min_value * (1f - h) - smoothing_min * h * (1f - h);
}

public NoiseLayer(NoiseLayerSettings.NoiseLayer noise_layer)
{
// sets noise
noise = new FastNoiseLite(noise_layer.general_noise.seed);
noise.SetFrequency(noise_layer.general_noise.frequency);
noise.SetNoiseType(noise_layer.general_noise.noise_type);

noise.SetFractalType(noise_layer.fractal.fractal_type);
noise.SetFractalOctaves(noise_layer.fractal.octaves);
noise.SetFractalLacunarity(noise_layer.fractal.lacunarity);
noise.SetFractalGain(noise_layer.fractal.gain);
noise.SetFractalWeightedStrength(noise_layer.fractal.weighted_strength);
noise.SetFractalPingPongStrength(noise_layer.fractal.ping_pong_strength);

noise.SetCellularDistanceFunction(noise_layer.cellular.cellular_distance_function);
noise.SetCellularReturnType(noise_layer.cellular.cellular_return_type);
noise.SetCellularJitter(noise_layer.cellular.jitter);

// domain warp
warp = new FastNoiseLite(noise_layer.general_noise.seed);
warp.SetDomainWarpType(noise_layer.domain_warp.domain_warp_type);
warp.SetDomainWarpAmp(noise_layer.domain_warp.amplitude);
warp.SetFrequency(noise_layer.domain_warp.frequency);

warp.SetFractalType(noise_layer.domain_warp_fractal.fractal_type);
warp.SetFractalOctaves(noise_layer.domain_warp_fractal.octaves);
warp.SetFractalLacunarity(noise_layer.domain_warp_fractal.lacunarity);
warp.SetFractalGain(noise_layer.domain_warp_fractal.gain);

enabled = noise_layer.enabled;

amplitude = noise_layer.general.amplitude;
offsett = noise_layer.general.offsett;

min_value = noise_layer.general.min_value;
smoothing_max = Mathf.Max(0f, noise_layer.general.smoothing_max);
max_value = noise_layer.general.max_value;
smoothing_min = Mathf.Min(0f, -noise_layer.general.smoothing_min);
}

public float GetNoiseValueColor(float x, float z)
{
x += offsett.x;
z += offsett.y;
warp.DomainWarp(ref x, ref z);
float noise_value = noise.GetNoise(x, z);
noise_value = (noise_value + 1f) * 0.5f;
noise_value = SmoothMin(noise_value);
noise_value = SmoothMax(noise_value);
return noise_value;
}

public float GetNoiseValue(float x, float z)
{
return GetNoiseValueColor(x, z) * amplitude;
}

public Texture2D GetNoiseTexture(Vector2Int texture_size)
{
Texture2D noise_texture = new Texture2D(texture_size.x, texture_size.y);
for (int x = 0; x < texture_size.x; x++)
{
for (int y = 0; y < texture_size.y; y++)
{
float noise_value = GetNoiseValueColor(x, y);

Color color = new Color(noise_value, noise_value, noise_value);
noise_texture.SetPixel(x, y, color);
}
}
noise_texture.Apply();
return noise_texture;
}
}
__
Full Error:
InvalidOperationException: Noise+NoiseLayer used in NativeArray<Noise+NoiseLayer> must be unmanaged (contain no managed types) and cannot itself be a native container type.
Unity.Collections.NativeArray1[T].IsUnmanagedAndThrow () (at <af218701fe324032b521ddd91f13662b>:0)*_</em></em></em></em> <em><em><em><em>_*Unity.Collections.NativeArray1[T].CheckAllocateArguments (System.Int32 length, Unity.Collections.Allocator allocator, System.Int64 totalSize) (at :0)
Unity.Collections.NativeArray1[T].Allocate (System.Int32 length, Unity.Collections.Allocator allocator, Unity.Collections.NativeArray1[T]& array) (at :0)
Unity.Collections.NativeArray`1[T]…ctor (Noise+NoiseLayer[] array, Unity.Collections.Allocator allocator) (at :0)
Chunk+d__10.MoveNext () (at Assets/World Generation/Chunk.cs:91)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at :0)

All I needed to do was:

class FastNoiseLite → struct FastNoiseLite

remove all field initializers.