I’m just starting out learning about threads in C#, so I wanted to integrate the most basic example of threading in my current project: Whenever I save a level map file, which may take enough time to make the framerate drop noticeably, I instead want the save method to happen on a new thread, so that the user doesn’t notice any lag while playing and saving.
Might this be worth it or is this a completely contrived example?
Am I doing anything horribly wrong in my following code? Are there any examples of good threaded code in Unity, which you would share or can link to?
public class MapController : MonoBehaviour
{
Map map;
void Start()
{
var threadStart = new ParameterizedThreadStart(SaveMapThreaded);
Thread thread = new Thread(threadStart);
thread.Start(Application.dataPath + "/level.map");
}
void SaveMapThreaded(object path)
{
var fileManager = new MapFileManager(new JsonMapSerializer());
fileManager.Save((string)path, map);
}
}
public class MapFileManager
{
IMapSerializer serializer;
// ...
public void Save(string path, Map map)
{
try
{
using (FileStream stream = File.Create(path))
{
Thread.Sleep(1000);
serializer.Serialize(stream, MapData.Convert(map));
}
}
catch (Exception ex)
{
// If serialization fails, clean up corrupted file.
if (File.Exists(path))
File.Delete(path);
throw ex;
}
}
}
public class JsonMapSerializer : IMapSerializer
{
// ...
public void Serialize(Stream stream, MapData data)
{
var serializer = new JsonSerializer();
using (var textWriter = new StreamWriter(stream))
using (var jsonWriter = new JsonTextWriter(textWriter))
{
serializer.Serialize(jsonWriter, data);
}
}
}
I’ve tested my code with a few Thread.Sleep() calls and it actually does what I want. Even if the save method stalls for a few seconds, the Unity main thread keeps on running smoothly. I know that usually you have to do things like use lock or mutex objects, prevent race conditions and dead locks, but as far as I can think, in my example, there’s not much that could go wrong, right? (I know that most of the Unity API is not threadsafe, but that’s fairly obvious when testing because of the clear exception thrown.)
Thanks for any feedback!