/// <summary> /// Method that receives messages /// </summary> private void ReceiveMessages() { while (ContinueExecution) { // Receive next message and handle it ReceiveRequest asyncReceive = null; lock (comm) { // starts an asynchronous receive of the next message // Note: Must be asynchronous otherwise the lock of the comm object may cause a dead lock (unable to send message because we are waiting for one) asyncReceive = comm.ImmediateReceive <Message>(Communicator.anySource, 0); } // Creates a task that waits for the result to arrive. // Note : We must use a task because the Wait function of a task allows for a timeout parameter which we need to validate if the execution is still ongoing Task waitForMessage = new Task(() => { asyncReceive.Wait(); }); waitForMessage.Start(); // waits for a message to be received, stops (within 200ms) if the execution stops while (ContinueExecution && !waitForMessage.Wait(200)) { ; } if (!ContinueExecution) { asyncReceive.Cancel(); // We need to wait for the asyncReceive cancellation because the completion of this thread will close MPI but we need to make sure the cancel is over by then. asyncReceive.Wait(); break; // if the execution is over, the message may not be valid and should be ignored. } messageQueue.Add((Message)asyncReceive.GetValue()); } // Signal the main MapManager thread that this thread is correctly closed and we won't receive any other messages messageQueue.CompleteAdding(); }