I would define an interface IActable (pick your name) which defines Act().  
public interface IActable
{
  void Act();
}
Make A, B, and C implement IActable.  Then, change your function to do the following.
private void Step()
{
    var all = new List<IActable>();
    all.AddRange(aList);
    all.AddRange(bList);
    all.AddRange(cList);
    all = all.Shuffle(new Random());
    foreach (IActable a in all)
    {
        a.Act();
    }
}
Shuffle method, stolen from here
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
    T[] elements = source.ToArray();
    // Note i > 0 to avoid final pointless iteration
    for (int i = elements.Length-1; i > 0; i--)
    {
        // Swap element "i" with a random earlier element it (or itself)
        int swapIndex = rng.Next(i + 1);
        T tmp = elements[i];
        elements[i] = elements[swapIndex];
        elements[swapIndex] = tmp;
    }
    // Lazily yield (avoiding aliasing issues etc)
    foreach (T element in elements)
    {
        yield return element;
    }
}
A parallel implementation using plinq.  (order not preserved)
private void Step()
    {
        var all = new List<IActable>();
        all.AddRange(aList);
        all.AddRange(bList);
        all.AddRange(cList);
        all.AsParallel().ForAll(a=>a.Act());
    }