Print message comes out in batches
PRINT output is buffered.  If you replace PRINT ... with RAISERROR ... WITH NOWAIT you will see results as they happen.

DECLARE @msg VARCHAR(MAX);
DECLARE @counter INT;
WHILE (@counter &lt; 50)
BEGIN
    BEGIN TRANSACTION
    SET @msg = 'Counter = ' + CONVERT(VARCHAR(4), @counter);
    RAISERROR (@msg, 0, 1) WITH NOWAIT;
    ;WITH CTE
    AS (
        SELECT TOP(50000) * 
        FROM MySchema.MyTable
        )
    DELETE FROM CTE OPTION (MAXDOP 1);
    SET @counter += 1;
    COMMIT TRAN
END