You'll sometimes need to perform actions that are technically "multithreaded" in that they use thread pool threads, but that fact is effectively transparent to you. Network communications, for example, is a series of asynchronous operations. You pass work onto your network interface card (NIC) and it does the work "in the background," and then informs you when the operation is completed.
Unfortunately in .NET, until Silverlight in 2007, operations in .NET that were inherently asynchronous had the option of being invoked entirely synchronously. For example, with an active TcpClient
object, we could send data to the host synchronously as follows:
public void Write(TcpClient tcpClient, byte[] data)
{
var networkStream = tcpClient.GetStream();
networkStream.Write(data, 0, data.Length);
// TODO: more, like invoke Read...
}
The call to Write
basically just tells the NIC to send the data, then blocks (doing nothing and not allowing the thread to be used for anything else...