Проблема при запуске потоков после остановки

Здравствуйте всех настоящим новым годом. Теперь о проблеме пытаюсь переписать(из winform в wpf/mvvm) код из ютубчика тут github:тут при остановки Stop() потоков из запуска Start() вылетает ошибка: System.InvalidOperationException:'Start may not be called on a task that has completed.' введите сюда описание изображения

ShopComputerModel

    /// <summary>
    /// Моделирование работы магазина касс.
    /// </summary>
    public class ShopComputerModel
    {
        Generator Generator = new Generator();
        Random rnd = new Random();
        List<Task> tasks = new List<Task>();
        CancellationTokenSource cancelTokenSource;
        CancellationToken token;
        /// <summary>
        /// Касса
        /// </summary>
        public List<CashDesk> CashDesks { get; set; } = new List<CashDesk>();
        public List<Cart> Carts { get; set; } = new List<Cart>();
        public List<Check> Checks { get; set; } = new List<Check>();
        /// <summary>
        /// Продажы
        /// </summary>
        public List<Sell> Sell { get; set; } = new List<Sell>();
        public Queue<Seller> Sellers { get; set; } = new Queue<Seller>();

        public int CustomerSpeed { get; set; } = 100;
        public int CashDeskSpeed { get; set; } = 100;

        public ShopComputerModel()
        {   
            var sellers = Generator.GetNewSellers(20);
            Generator.GetNewProducts(1000);
            Generator.GetNewCustomers(100);

            cancelTokenSource = new CancellationTokenSource();
            token = cancelTokenSource.Token;

            foreach (var seller in sellers)
            {
                Sellers.Enqueue(seller);
            }

            for(int i = 0; i < 3; i++)
            {
                CashDesks.Add(new CashDesk(CashDesks.Count, Sellers.Dequeue()));
            }
        }

        public void Start()
        {
            #region Синхронное выполные
            //var customers = Generator.GetNewCustomers(10);
            ////Заполные козины
            //var carts = new Queue<Cart>();
            //foreach (var customer in customers)
            //{
            //    var cart = new Cart(customer);

            //    foreach (var prod in Generator.GetRandomProducts(10, 30))
            //    {
            //        cart.Add(prod);
            //    }

            //    carts.Enqueue(cart);
            //}



            //while (carts.Count > 0)
            //{
            //    var cash = CashDesks[rnd.Next(CashDesks.Count - 1)];//случайная касса
            //    cash.Enqueue(carts.Dequeue());//Будем распределять покупателей по одной из 3 класс.
            //}
            
            //while (true)//Обслуживаные в кассе людей
            //{
            //    var cash = CashDesks[rnd.Next(CashDesks.Count - 1)];
            //    var money = cash.Dequeue();
            //}
            #endregion

            #region Асинхронные выполные
            tasks.Add(new Task(() => CreateCarts(10, token)));
            tasks.AddRange(CashDesks.Select(c => new Task(() => CashDeskWork(c, token))));
            foreach (var task in tasks)
            {
                task.Start();
            }
            #endregion
        }

        public void Stop()
        {
            cancelTokenSource.Cancel();
            Thread.Sleep(1000);
        }

        private void CashDeskWork(CashDesk cashDesk, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {   //Если человек есть в очереде,тогда облужаем его.
                if (cashDesk.Count > 0)
                {
                    cashDesk.Dequeue();
                    Thread.Sleep(CashDeskSpeed);
                }
            }
        }

        private void CreateCarts(int customerCounts, CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                var customers = Generator.GetNewCustomers(customerCounts);

                foreach (var customer in customers)
                {
                    var cart = new Cart(customer);
                    //Заполненные корзину продуктами.
                    foreach (var product in Generator.GetRandomProducts(10, 30))
                    {
                        cart.Add(product);
                    }
                    //Клиент будет выбирать из случайных очередей.
                    var cash = CashDesks[rnd.Next(CashDesks.Count)];
                    cash.Enqueue(cart);
                }

                Thread.Sleep(CustomerSpeed);
            }
        }
    }

Generator

/// <summary>
///Будет создавать виртуальные объекты(для системы сrm).
/// </summary>
public class Generator
{
    Random rnd = new Random();
    public List<Customer> Customers { get; set; } = new List<Customer>();
    public List<Product> Products { get; set; } = new List<Product>();
    public List<Seller> Sellers { get; set; } = new List<Seller>();
    /// <summary>
    /// Генерирование покупателей.
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    public List<Customer> GetNewCustomers(int count)
    {
        var result = new List<Customer>();

        for(int i = 0; i < count; i++)
        {
            var customer = new Customer()
            {
                CustomerId = Customers.Count,
                Name = GetRandomText(),
                Password= GetRandomText()
            };
            Customers.Add(customer);
            result.Add(customer);
        }

        return result;
    }
    /// <summary>
    ///Генерирование продавцов.
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    public List<Seller> GetNewSellers(int count)
    {
        var result = new List<Seller>();

        for (int i = 0; i < count; i++)
        {
            var seller = new Seller()
            {
                SellerId = Sellers.Count,
                Name = GetRandomText()
            };
            Sellers.Add(seller);//будем сохранить продавцов
            result.Add(seller);//тут будем возвращать продавцов
        }

        return result;
    }
    /// <summary>
    /// Генерирование товаров.
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    public List<Product> GetNewProducts(int count)
    {
        var result = new List<Product>();

        for (int i = 0; i < count; i++)
        {
            var product = new Product()
            {
                ProductId = Products.Count,
                Name = GetRandomText(),
                Count = rnd.Next(10, 1000),
                Price = Convert.ToDecimal(rnd.Next(5, 100000) +  rnd.NextDouble())
            };
            Products.Add(product);
            result.Add(product);
        }

        return result;
    }
    /// <summary>
    /// Полученые товаров какие есть уже
    /// </summary>
    /// <param name="min"></param>
    /// <param name="max"></param>
    /// <returns></returns>
    public List<Product> GetRandomProducts(int min, int max)
    {
        var result = new List<Product>();

        var count = rnd.Next(min, max);//будем получать счуйное количество товаров
        for(int i = 0; i < count; i++)
        {
            result.Add(Products[rnd.Next(Products.Count - 1)]);
        }
        return result;
    }

    private static string GetRandomText()
    {
        return Guid.NewGuid().ToString().Substring(0, 5);
    }
}

Ответы (1 шт):

Автор решения: VladD

У вас список List<Task> tasks = new List<Task>(); не опустошается после выполнения заданий. При втором выполнении функции Start в списке есть ещё старые, выполненные задания.

→ Ссылка