Note: Please read to the end before marking as duplicate. I've read the other answers, and they don't seem to answer my question.
I've seen various pictures and people point out and say that multithreading is different from asynchronous programming, by giving various analogies to restaurant workers and the like. But I've yet to see the difference with an actual example.
I tried this in C#:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace AsyncTest
{
class Program
{
static void RunSeconds(double seconds)
{
int ms = (int)(seconds * 1000);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine($"Thread started to run for {seconds} seconds");
Thread.Sleep(ms);
stopwatch.Stop();
Console.WriteLine($"Stopwatch passed {stopwatch.ElapsedMilliseconds} ms.");
}
static async Task RunSecondsAsync(double seconds)
{
int ms = (int)(seconds * 1000);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine($"Thread started to run for {seconds} seconds");
await Task.Run(() => Thread.Sleep(ms));
stopwatch.Stop();
Console.WriteLine($"Stopwatch passed {stopwatch.ElapsedMilliseconds} ms.");
}
static void RunSecondsThreaded(double seconds)
{
Thread th = new Thread(() => RunSeconds(seconds));
th.Start();
}
static async Task Main()
{
Console.WriteLine("Synchronous:");
RunSeconds(2.5); RunSeconds(2);
Console.WriteLine("\nAsynchronous:");
Task t1 = RunSecondsAsync(2.5); Task t2 = RunSecondsAsync(2);
await t1; await t2;
Console.WriteLine("\nMultithreading:");
RunSecondsThreaded(2.5); RunSecondsThreaded(2);
}
}
}
Results:
Synchronous:
Thread started to run for 2.5 seconds
Stopwatch passed 2507 ms.
Thread started to run for 2 seconds
Stopwatch passed 2001 ms.
Asynchronous:
Thread started to run for 2.5 seconds
Thread started to run for 2 seconds
Stopwatch passed 2002 ms.
Stopwatch passed 2554 ms.
Multithreading:
Thread started to run for 2.5 seconds
Thread started to run for 2 seconds
Stopwatch passed 2000 ms.
Stopwatch passed 2501 ms.
They yielded essentially the same results, behaviour-wise. So when and what exactly would I find different in the behaviour of a multithreaded program vs an asynchronous one?
I have various other issues to resolve:
In this image, for example:
What I don't get is that when you run an asynchronous program, it behaves practically identically to a multithreaded one, in that it seems to spend a similar amount of time. By the image above, it's addressing the asynchronous task in "breaks". If it does this, shouldn't it take longer for the asynchronous task to complete?
Let's say an asynchronous task which would normally complete 3 seconds synchronously while locking other tasks is run, should I not expect these tasks to finish in much longer than 3 seconds, given that it does other tasks on the side while taking breaks from my original task?
So why does it often take a similar asynchronously (ie. the usual 3 seconds)? And why does the program become "responsive": if the task is not being done on a separate thread, why does working on the task while working on other tasks on the side take only the expected 3 seconds?
The problem I have with the examples using workers in a restaurant (see top answer), is that in a restaurant, the cooking is done by the oven. In a computer, this analogy doesn't make much sense, as it's not clear why the oven isn't being treated as a separate "thread" but the people/workers are.
Furthermore, does a multithreaded application use more memory? And if it does, is it possible to create a simple application (ideally as similar to the one above) proving that it does?
Bit of a lengthy question, but the differences between multithreading and asynchronous programming are far from clear to me.