Q:

Observable that cyclicly pushes a list of values

I want to create an Observable that keeps pushing a list of values every t seconds. 
For example, given the {1, 2, 3, 4} subscribers should get this:
1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2...
class Program
{
    static void Main()
    {
        var observable = Observable
            .Interval(TimeSpan.FromSeconds(3))
            .Zip(Observable.Range(1, 4)
            .Repeat(), (_, count) => count);

        observable.Subscribe(Console.WriteLine);

        Console.WriteLine("Finished!");
    }
}

I have worked on this example and it seems to work, but with a very nasty problem: the Main method never ends its execution! Why? :(
And even worse, after some minutes, this console application throws an OutOfMemoryException!

A:

this seems like a simple mis-placed .Repeat() to me.
class Program
{
    static void Main()
    {
        var observable = Observable
            .Interval(TimeSpan.FromSeconds(3))
            .Zip(Observable.Range(1, 4), (_, count) => count)
            .Repeat();

        observable.Subscribe(Console.WriteLine);

        Console.WriteLine("Finished!");
        Console.ReadLine();
    }
}

This will now:

Not block the console from finishing
Not throw an OutOfMemoryException.

Note, no use of .Do(), no custom extension methods, no endless yielding of IEnumerables that block the thread ;-)
...and an alternate implementation without Zip so that hopefully a layman dev could read and understand (with disposal too!):
class Program
{
    static void Main()
    {
        var observable = Observable
            .Interval(TimeSpan.FromSeconds(3))
            //.Zip(Observable.Range(1, 4), (_, count) => count)
            .Select(i=>i+1)
            .Take(4)
            .Repeat();

        using (observable.Subscribe(Console.WriteLine))
        {
            Console.WriteLine("Running...");
            Console.ReadLine();
        }
        Console.WriteLine("Finished!");
    }
}

A:

I've removed my suggested answer, as both Timothy & Lee's answers use built-in Rx functions and are far more elegant.  I will leave the explanation of the issue, though, as I believe it's useful:
Observables are expected to be push sequences, and Zip will queue items from the faster producing stream while it waits for a value from the second to pair with the next.  As Obsevable.Range returns these values as quick as the subscriber can handle, this fills all your memory and blocks the thread.

