I've started with the simplest form I could think of: my task system. It is a very simple system: I create a Task class, instantiate it, add it to the manager and the manager updates it every tick until it is finished. For the test, I created a very basic base class, AsyncTask, which handles the initialization and such. I then implemented a LoadTextFileTask and AsyncLoadTextTask, both of which do the same job (streaming all of the data in the file into memory.)
The problem is, I have no clue if I'm even really doing this properly or if I'm way off the mark. So, if anyone is willing to take a gander, I'd greatly appreciate any input. Here is the AsyncTask:
[source]
public class AsyncTask : Dubnium2D.Core.Task
{
private object lockObject = new object();
protected Thread thread = null;
protected bool CrossThreadCheck
{
get
{
lock(lockObject)
{
return Thread.CurrentThread != thread;
}
}
}
public AsyncTask(bool DelayStart = false)
{
thread = new Thread(() =>
{
Utilities.Timing.ProfileTimer Timer = new Utilities.Timing.ProfileTimer();
while(true)
{
Timer.Update();
lock(lockObject)
{
if(this.IsDead)
break;
if(this.IsPaused)
continue;
}
this.Update(Timer.Delta);
}
Kill();
});
if(!DelayStart)
thread.Start();
}
public override void Update(float Delta)
{
if(CrossThreadCheck)
{
if(IsDead || IsPaused || thread.ThreadState != ThreadState.Running)
return;
if(thread.ThreadState == ThreadState.Unstarted)
thread.Start();
return;
}
base.Update(Delta);
}
}
[/source]
And here is the AsyncLoadTextTask class:
[source]
public sealed class AsyncLoadTextTask : AsyncTask
{
private object lockObject = new object();
private System.IO.StreamReader reader = null;
private char[] data = null;
private int currentIndex = 0;
private int bufferSize = 0;
private int length = 0;
private string filePath = string.Empty;
private int progress = 0;
private int charactersRemaining
{
get
{
lock(lockObject)
{
return length - currentIndex;
}
}
}
///
/// Gets the path to the file that is being loaded.
///
public string FilePath
{
get
{
lock(lockObject)
{
return filePath;
}
}
private set
{
lock(lockObject)
{
filePath = value;
}
}
}
///
/// Gets the data that was loaded from the file. Will throw an exception if the loading process is not finished.
///
public string Data
{
get
{
lock(lockObject)
{
if(!IsDead)
throw new InvalidOperationException();
return new string(data);
}
}
}
///
/// Gets the progress of the load process.
///
public int Progress
{
get
{
lock(lockObject)
{
return progress;
}
}
private set
{
lock(lockObject)
{
progress = value;
}
}
}
///
/// Initializes a new instance of the class.
///
/// The path to the file to load into memory.
/// Size of the buffer to use when loading the data.
public AsyncLoadTextTask(string FilePath, int BufferSize)
{
this.FilePath = FilePath;
reader = new System.IO.StreamReader(FilePath);
this.length = (int)reader.BaseStream.Length;
this.data = new char[length];
this.bufferSize = BufferSize;
}
///
/// Updates the task using the supplied time delta.
/// If the task was created with DelayStart = true, then calling this from outside of the task's thread will start it. Otherwise, calling it from outside of the task's thread will do nothing.
///
/// The time, in seconds, since the last update.
public override void Update(float Delta)
{
base.Update(Delta);
if(CrossThreadCheck)
return;
lock(lockObject)
{
int BytesRead = reader.Read(data, currentIndex, Math.Min(charactersRemaining, bufferSize));
currentIndex += BytesRead;
this.Progress = (int)(100.0f * ((float)currentIndex / (float)length));
if(currentIndex >= length)
{
this.reader.Close();
this.reader.Dispose();
Kill();
}
}
}
}
[/source]
Again, any input will be greatly appreciated.