Background Thread Error

Discussion and help for Easy Save 3
Post Reply
Byte2020
Posts: 2
Joined: Mon May 18, 2020 5:22 am

Background Thread Error

Post by Byte2020 »

Hi, I am running into NullReferenceException when calling Load from a background thread some of the time. (full error log below) Some other times, it runs OK.

I setup ES3 to load from background thread using System.Thread. I am using Version: 3.3.1f2 • May 13, 2020

The simplified code

Code: Select all

     
       // Main Thread
        public LoadFromDisk()
        {
            ES3Settings settings = new ES3Settings();
            Thread thread = new Thread(() => LoadAndUpdateValues(settings));
            thread.Start();
        }

        // Background Thread
        protected void LoadAndUpdateValues(ES3Settings settings)
        {
            string path = GetPathString;
            Foo foo = ES3.Load<Foo>(path, path, settings);

            // Update Values.
        }
I tried some other ways as well, like using the two below with the same inconsistency results.

Code: Select all

ES3.Load<Foo>(path, settings);
//or
reader.Read<Foo>(key)
Error log

Code: Select all

NullReferenceException: Object reference not set to an instance of an object
System.Collections.Generic.Dictionary`2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Collections.Generic.Dictionary`2[TKey,TValue].set_Item (TKey key, TValue value) (at <437ba245d8404784b9fbab9b439ac908>:0)
ES3Internal.ES3TypeMgr.Add (System.Type type, ES3Types.ES3Type es3Type) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:47)
ES3Types.ES3Type..ctor (System.Type type) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3Type.cs:29)
ES3Types.ES3Type_ES3Prefab..ctor () (at Assets/Plugins/Easy Save 3/Scripts/ES3Prefab.cs:139)
System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) (at <437ba245d8404784b9fbab9b439ac908>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) (at <437ba245d8404784b9fbab9b439ac908>:0)
System.Activator.CreateInstance (System.Type type) (at <437ba245d8404784b9fbab9b439ac908>:0)
ES3Internal.ES3Reflection.GetInstances[T] () (at Assets/Plugins/Easy Save 3/Scripts/ES3Reflection.cs:312)
ES3Internal.ES3TypeMgr.Init () (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:127)
ES3Internal.ES3TypeMgr.GetOrCreateES3Type (System.Type type, System.Boolean throwException) (at Assets/Plugins/Easy Save 3/Scripts/Types/ES3TypeMgr.cs:18)
ES3Reader.Read[T] (System.String key) (at Assets/Plugins/Easy Save 3/Scripts/Readers/ES3Reader.cs:181)
ES3.Load[T] (System.String key, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:374)
ES3.Load[T] (System.String key, System.String filePath, ES3Settings settings) (at Assets/Plugins/Easy Save 3/Scripts/ES3.cs:358)
//...LoadAndUpdateValues

User avatar
Joel
Moodkie Staff
Posts: 2755
Joined: Wed Nov 07, 2012 10:32 pm

Re: Background Thread Error

Post by Joel »

Hi there,

If you're running in a separate thread to improve performance, I would actually recommend storing to cache as described here. This eliminates the overhead of random access, and doesn't require any

If you absolutely need to run in a separate thread, it's first worth mentioning that much of Unity's API is not thread safe, so you should ensure that the type of data you're loading is itself thread safe.

If using it in another thread, you should also ensure that Easy Save is only used in one thread at a time. The error you're receiving occurs when two threads try to modify the ES3Types Dictionary at the same time.

It would also be worth called ES3.Init() synchronously in the main thread before calling any Easy Save methods asynchronously.

All the best,
Joel
Joel @ Moodkie Interactive
Twitter - Unity

Byte2020
Posts: 2
Joined: Mon May 18, 2020 5:22 am

Re: Background Thread Error

Post by Byte2020 »

Thank Joel,

It is indeed the race condition accessing ES3Types, introducing a lock works reliably.
I will look into the cache options.

Best,
Byte

Post Reply