The reason the "do { stuff1; stuff2; } while (0)" idiom is preferred over "(stuff1,stuff2)" is that the former is a statement, and the latter is an expression: the former does not yield any value, whereas the latter yields the value of the final expression.
That is, if you have
#define STROBE1 do { PORTBbits.RB5=1; PORTBbits.RB5=0; } while (0)
#define STROBE2 (PORTBbits.RB5=1,PORTBbits.RB5=0)
you can do e.g.
a = STROBE2;
but you cannot do
a = STROBE1;
Only when the macro should evaluate to some (useful) value, the comma-based one is preferred.
Some compilers, like GCC, clang, and ICC, support an extension to C, where a code scope can be treated as an expression:
#define TOGGLE ({ int _bit = PORTBbits.RB5; PORTBbits.RB5 = !_bit; _bit; })
This is much like a normal code block, except that because it is in parenthesis, it behaves like a single expression, yielding the value of the final expression in the scope. Above, it yields the value of _bit, i.e. the state of the port B pin 5 before the toggle. Do remember that this is not standard C, and is not portable across all C compilers, though. It is just common enough so it makes sense to recognize it and its uses. For example,
if (TOGGLE) {
/* Port B pin 5 was HIGH, now toggled to LOW. */
} else {
/* Port B pin 5 was LOW, now toggled to HIGH. */
}