Task.WhenAll(): Остановить все задачи, если одна провалилась

Часто так бывает, что находишь решение (пусть и кривое) одной проблемы, как тут же всплывает другая, ещё более непонятная.
Есть код:

        private async void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            System.Diagnostics.Debug.WriteLine("button is pressed");

            int n = await Task.Run(() => Go());

            button1.Enabled = true;
        }

        private async Task<int> Go()
        {
            int[] ids = new int[] { 0, 1, 2, 3, 4, 5, 6 };
            var tasks = ids.Select(id => Task.Run(() =>
            {
                Random random = new Random();
                //симулируем разную скорость выполнения задач
                int delay = id == 0 ? 2000 : random.Next(3000, 5000);
                int i = 0;
                while (i < 10)
                {
                    string t = $"Task №{id}: {++i}";
                    System.Diagnostics.Debug.WriteLine(t);
                    Thread.Sleep(delay);
                    if (id == 0 && i == 3)
                    {
                        //симулируем ошибку
                        throw new Exception("reached");
                    }
                }

                System.Diagnostics.Debug.WriteLine($"Task №{id} is finished");
            }));

            try
            {
                await Task.WhenAll(tasks);
            } catch (Exception ex)
            {
                //сюда заходит только когда все таски завершились
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
            return 0;
        }

Если в одной таске произошла ошибка, как остановить все остальные? :thinking:

Создать общий CancellationToken, и в таске при ошибке отменять его.
Например как тут c# - How to properly cancel Task.WhenAll and throw the first exception? - Stack Overflow