Yes, it is possible to do using iterators. I've put some pseudo C# code here to give you an idea. You use yield return to return something from an iterator, which has the same behavior as yield in a theoretical coroutine. You can then store the iterators in a list, dictionary, or other structure to keep track of them, and run them all. Note that coroutines are not a natively supported feature of C#, and are usually implemented using enumerators. I think Unity does it in the same way.
enum Status
{
Running, Success, Failure
}
// An example of a coroutine that does something until some
// condition is true.
IEnumerable<Status> Coroutine(arguments)
{
while(true)
{
DoStuff();
yield return Running;
if(Condition())
{
yield return Success;
break;
}
}
}
// Keeps track of all running coroutines, and runs them till the end.
class CoroutineManager
{
List<IEnumerator<Status> > Coroutines = new List<Enumerator<Status> >();
// Starting a coroutine just means adding an enumerator to the list.
// You might also want to be able to stop coroutines or delete them,
// which might mean putting them into a dictionary
public void StartCoroutine(Func<IEnumerable<Status> > func)
{
Coroutines.Add(func().GetEnumerator());
}
// Updating just means stepping through all the coroutines
public void Update()
{
foreach(Enumerator<Status> routine in Coroutines)
{
routine.MoveNext();
}
}
}
You then just need to call
CoroutineManager.StartCoroutine(YourFunction)
to begin the coroutine. Somewhere in your code you also need to call
CoroutineManager.Update();
each tick.