Lets clear up the terminology here, as the buzzy terms are being used more often and we expect to hear more about them in the future. Concurrency, Multi-threading, Parallel Processing, and Asynchrony.
Concurrency: Doing more than a thing at the same time, this doesn’t mean multi-threading, multi-threading is a way for achieving concurrency but it’s not the only way.
Multithreading: Using more than one thread. Threads usually refer to OS threads and these are really expensive and you shouldn’t be using them directly in your code. In C#, feel free to go and delete every Thread you have. It’s only acceptable to use threads if you calling Sleep with the argument zero.
This call to Sleep is very different from any call to Sleep with non zero arguments, it means relinquish control to any thread of equal priority that is ready to run; if no such thread exists, do not relinquish control. Multi-threading is hard to get right especially if all what you know about threading is creating an instance of the class Thread, and hence you should use a higher abstraction that does pooling and thread caching for you.
Parallel Processing: Dividing a unit of work among multiple threads that run in parallel. That is, dividing the work into multi-threads to maximise the use of multi processors where these threads can run on different cores independently.
Asynchrony: Is an aspect of concurrency where Futures or Callbacks could be used to avoid creating heavy OS threads. A promise represents an operation that will complete in the future, and this doesn’t mean that a thread will be created for this operation.