FreeRTOS - Why is vTaskDelay needed here?

Ive written some test-code to see how the FreeRTOS works. The code simply reads an input on the serial port and returns it with some extra text. It also blinks a LED. The code works fine, but one thing puzzels me. Why do I need the vTaskDelay() in the TaskTransmit(). Both threads have the same priority.

The code:

#include <Arduino_FreeRTOS.h>
#include <semphr.h>

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// Store the read in this structure.
SemaphoreHandle_t xSerialSemaphore;
typedef struct {
    char str[64];
    bool ready;
  } Message_t;

volatile Message_t message;

// the setup function runs once when you press reset or power the board
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB, on LEONARDO, MICRO, YUN, and other 32u4 based boards.
  }

  if ( xSerialSemaphore == NULL )  // Check to confirm that the Serial Semaphore has not already been created.
  {
    xSerialSemaphore = xSemaphoreCreateMutex();  // Create a mutex semaphore we will use to manage the Serial Port
    if ( ( xSerialSemaphore ) != NULL )
      xSemaphoreGive( ( xSerialSemaphore ) );  // Make the Serial Port available for use, by "Giving" the Semaphore.
  }

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskRead
    ,  (const portCHAR *)"Read"   // A name just for humans
    ,  128  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  1  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL );

  xTaskCreate(
    TaskTransmit
    ,  (const portCHAR *) "Transmit"
    ,  128  // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL );


  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{

  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskTransmit(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  char buffer[64];
  for (;;)
  {
   if (message.ready)
    {
      xSemaphoreTake( xSerialSemaphore, portMAX_DELAY );
      strcpy( buffer, message.str );
      message.ready = false; 
      xSemaphoreGive( xSerialSemaphore );

      // Reflect the message back...
      Serial.print("Answer: ");
      Serial.print(buffer);
      
    }

    // Without this line nothing is transmitted back! And the LED will blink randomly.
    vTaskDelay(0);
  }
  

}

void myReadln(char *buffer)
{
  bool eol = false;
  unsigned int index = 0;
  const char NEWLINE = 10;
  while (!eol)
  {
    if (Serial.available())
    {
      char ch = Serial.read();
      buffer[index++] = ch;
      if (ch == NEWLINE || index > 62)
      {
        eol = true;
        buffer[index] = 0;
      }
    }
  }
  
  
}

void TaskRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  pinMode(LED_BUILTIN, OUTPUT);

  char buffer[64];
  bool tmp = false;
  for (;;)
  {
    
    digitalWrite(LED_BUILTIN, tmp);
    tmp = !tmp;
    if (message.ready == false)
     if (Serial.available())
     {
      myReadln(buffer);
      xSemaphoreTake( xSerialSemaphore, portMAX_DELAY );
      strcpy(message.str, buffer);
      message.ready = true;
      xSemaphoreGive( xSerialSemaphore );
     }

   // vTaskDelay(1); // Not needed
  }
}

It's probably there to give another task some time to run. This is an Arduino, after all.

Paul