/// <summary>
		/// Wait for the task to complete, where possible another task will be performed while waiting
		/// </summary>
		public void WaitForCompletion()
		{
			if (task == null)
				return;

			//is task still active?
			if (task.id == this.id)
			{
				//try and grab the task.
				IAction acton = Interlocked.Exchange(ref task.action, null);

				if (acton != null) // action gets nulled when the task is being run...
				{
					//run it now!
					acton.PerformAction(task.data);
					task.pool.ClearTask(task);
				}
				else
				{
					//something else is running the task?...
					while (task.id == this.id)
					{
						//if so, do something else while waiting (if possible)
						if (!task.pool.RunQueueTask())
							Thread.Sleep(0); // otherwise sleep.
					}
				}
			}

			//nullify
			this = new WaitCallback();
		}
		//internal update method
		UpdateFrequency IUpdate.Update(UpdateState state)
		{
			if (disposed)
				return UpdateFrequency.Terminate;

			if (systemData == null)
				return UpdateFrequency.FullUpdate60hz;

			//draw proc only makes it's callback if system isn't null
			drawProc.system = null;

			if (enabled)
			{
				//system logic is performed as a thread task
				threadWaitCallback.WaitForCompletion();

				if (!pauseUpdatesWhileCulled ||
					this.drawProc.AnyChildDrawnLastFrame)
				{
					//particle system is enabled, and isn't offscreen
					BufferSpawnData();


					//start the task
					threadWaitCallback = state.Application.ThreadPool.QueueTask(threadAction, null);

					//draw proc only makes it's callback if system isn't null
					drawProc.system = this;
				}
			}

			//asks the application to call Draw() on the drawProc when the frame begins
			//as currnetly in update()
			state.PreFrameDraw(drawProc);

			return systemLogic.UpdateFrequency;
		}
			UpdateFrequency IUpdate.Update(UpdateState state)
			{
				if (disposed)
					return UpdateFrequency.Terminate;

				if (!wasDrawn)
				{
					bool alive = false;
					foreach (WeakReference wr in this.parents)
					{
						if (wr.IsAlive)
						{
							alive = true;
							break;
						}
					}
					if (!alive)
					{
						this.parents.Clear();
						this.isAsync = false;
						return UpdateFrequency.Terminate;
					}
				}

				this.deltaTime = state.DeltaTimeSeconds;

				if (wasDrawn && ContentLoaded)
				{
					BufferAnimationValues();
					this.waitCallback = state.Application.ThreadPool.QueueTask(this, null);
				}
				else
					wasSkipped = true;
				wasDrawn = false;

				//using async here would be slower...
				return UpdateFrequency.OncePerFrame;
			}