Sorry, a series of things got posted while I was frothing over that busy wait.

The proper solution is not quite as easy to show, because it involves a conceptual shift. The proper way to do this is to add a timer component to your form. Set the interval of that timer to 4000 (because the interval is in milliseconds, so 4000 milliseconds would be 4 seconds). Double click on the timer to go to the timer tick event handler. In that handler is where the serialport Send operation should be located.

The other part is setting up the things to send. I don't know what those packets are, but I would guess that they are arrays of bytes. Therefore, add a Queue (of Byte()) at form scope. Wherever you are currently doing the sending, change the code so that you are enqueueing each packet rather than sending them. Once you have enqueued all your packets you can start the timer.

What is happening in the timer tick is that it checks the queue to see that the count > 0. If it is, dequeue the next item and send it. Once the count = 0, stop the timer.

That's the way to do it in a single thread. DB has a solution that would send all of those items in a background thread, which has certain advantages, but might be more difficult to implement if you aren't familiar with threads. Either way, the queue is a good idea. In fact, you could just leave the timer running and whenever you enqueue something, it will be sent when the timer gets to it.