C# 永久操作多任务

C# 永久操作多任务,c#,multitasking,C#,Multitasking,我正在研究多任务处理,我用windows窗体找到了一个非常简单的解决方案。 我有一个名为“车”的对象列表: 我想在“多会话(任务)”中做一些工作 假设我的“汽车”有两种方法:StartFullEngine()和GoDrive(),这是我在CarBusiness.cs中编写的,我想将一些消息输出到richtextbox。我有一个固定的10辆车的列表,会话的数量将代表上街的车的数量(几乎在同一时间),但是当他们在街上时,他们总是做同样的事情。即: 启动fullengine()。启动后,转到下一步:

我正在研究多任务处理,我用windows窗体找到了一个非常简单的解决方案。

我有一个名为“车”的对象列表:

我想在“多会话(任务)”中做一些工作

假设我的“汽车”有两种方法:
StartFullEngine()
GoDrive()
,这是我在
CarBusiness.cs
中编写的,我想将一些消息输出到
richtextbox
。我有一个固定的10辆车的列表,会话的数量将代表上街的车的数量(几乎在同一时间),但是当他们在街上时,他们总是做同样的事情。即:

  • 启动fullengine()
    。启动后,转到下一步:
  • GoDrive()
    。这可以异步执行,而另一个任务将从列表中选择下一辆车并返回到步骤1。它将永远停留在这个循环中,但不会耗尽会话
  • 为了实现这一目标,我做了以下工作:

    CarBusiness.cs:

    public class CarBusiness
    {
        private RichTextBox _richTextBox;
        private static readonly object syncLock = new object();
        private Car _carToRun;
        private Random random;
        public CarBusiness(Car car, RichTextBox richTextBox)
        {
            _carToRun = car;
            _richTextBox = richTextBox;
            random = new Random();
        }
    
        private void OutputMessage(string msg)
        {
            lock (syncLock)
            {
                _richTextBox.BeginInvoke((Action)(() =>
                {
                    _richTextBox.AppendText($"#{_carToRun.Id}: [{DateTime.Now.Hour.ToString("D2")}:{DateTime.Now.Minute.ToString("D2")}:{DateTime.Now.Second.ToString("D2")}] - {msg}\r\n");
                }));
    
            }
        }
    
        public Task StartFullEngine()
        {
            return Task.Run(async () =>
            {
                var start = DateTime.Now;
                await Task.Delay(random.Next(1000, 10000));
                var end = DateTime.Now;
                TimeSpan timeDiff = start - end;
                var readableDiff = string.Format(
                    "{0:D2} hrs, {1:D2} mins, {2:D2} secs",
                    timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds);
                OutputMessage($"Full engined finished. Time ellapsed: {readableDiff}");
            });
        }
    
        public Task GoDrive()
        {
            return Task.Run(async () =>
            {
                var start = DateTime.Now;
                await Foo();
                Boo().Wait();
                var end = DateTime.Now;
                TimeSpan timeDiff = start - end;
                var readableDiff = string.Format(
                    "{0:D2} hrs, {1:D2} mins, {2:D2} secs",
                    timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds);
                OutputMessage($"GoDrive() finished. Time ellapsed: {readableDiff}");
            });
        }
    
    
        private Task Foo()
        {
            return Task.Run(async () =>
            {
                //long operation
                OutputMessage($"Running Foo()...");
                await Task.Delay(random.Next(1000, 3000));
                OutputMessage($"Foo() ended!");
            });
        }
    
    
        private Task Boo()
        {
            return Task.Run(async () =>
            {
                OutputMessage($"Running Boo()...");
                await Task.Delay(random.Next(10000, 30000));
                OutputMessage($"Boo() ended!");
            });
        }
    }
    
    public class CarDao
    {
        public List<Car> GetListOfCar()
        {
            var list = new List<Car>();
            for (int i = 1; i <= 10; i++)
                list.Add(new Car { Id = i, Status = Status.Standby });
    
            return list;
        }
    }
    
    public partial class Form1 : Form
    {
        private List<Car> listOfCars;
        private object objInstances = new object();
        public Form1()
        {
            InitializeComponent();
        }
        private Task<Car> GetNextCar()
        {
            return Task.Run(() =>
            {
                lock (objInstances)
                {
                    //Need a logic to prioritize getting cars that have never "run" before
                    var nextCar = listOfCars.Where(x => x.Status != Status.Running).SkipWhile(x => x.Status == Status.Finished).FirstOrDefault();
                    return nextCar;
                }
            });
        }
        private Task<List<Car>> GetInstances(Status statusCar)
        {
            return Task.Run(() =>
            {
                lock (objInstances)
                {
                    return listOfCars.Where(x => x.Status == statusCar).ToList();
                }
            });
        }
    
        private async void button1_Click(object sender, EventArgs e)
        {
            var carDao = new CarDao();
    
            //NumericUpDown value
            var maxSessions = numberOfSessions.Value;
    
            //fixed list of cars
            listOfCars = carDao.GetListOfCar();
    
            //Never stop running
            while (true)
            {
                var runningInstances = GetInstances(Status.Running).Result;
    
                for (int i = runningInstances.Count(); i < maxSessions; i++)
                {
                    var carToRun = GetNextCar().Result;
                    carToRun.Status = Status.Running;
    
                    var carBusiness = new CarBusiness(carToRun, richTextBox);
    
                    Task.Run(() =>
                    {
                        //First thing: StartFullEngine()
                        carBusiness.StartFullEngine().Wait();
                    }).Wait();
    
                    //After started Engine, GoDrive() can run asynchronously.
                    await Task.Run(() =>
                   {
                       carBusiness.GoDrive().Wait();
                       carToRun.Status = Status.Finished;
                   });
                    //Next loop;
                }
                //logic to wait some tasks get done to start again
                runningInstances = GetInstances(Status.Running).Result;
                if (runningInstances.Count() == maxSessions)
                    Task.Delay(20000).Wait();
            }
    
        }
    }
    
    CarDao.cs:

    public class CarBusiness
    {
        private RichTextBox _richTextBox;
        private static readonly object syncLock = new object();
        private Car _carToRun;
        private Random random;
        public CarBusiness(Car car, RichTextBox richTextBox)
        {
            _carToRun = car;
            _richTextBox = richTextBox;
            random = new Random();
        }
    
        private void OutputMessage(string msg)
        {
            lock (syncLock)
            {
                _richTextBox.BeginInvoke((Action)(() =>
                {
                    _richTextBox.AppendText($"#{_carToRun.Id}: [{DateTime.Now.Hour.ToString("D2")}:{DateTime.Now.Minute.ToString("D2")}:{DateTime.Now.Second.ToString("D2")}] - {msg}\r\n");
                }));
    
            }
        }
    
        public Task StartFullEngine()
        {
            return Task.Run(async () =>
            {
                var start = DateTime.Now;
                await Task.Delay(random.Next(1000, 10000));
                var end = DateTime.Now;
                TimeSpan timeDiff = start - end;
                var readableDiff = string.Format(
                    "{0:D2} hrs, {1:D2} mins, {2:D2} secs",
                    timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds);
                OutputMessage($"Full engined finished. Time ellapsed: {readableDiff}");
            });
        }
    
        public Task GoDrive()
        {
            return Task.Run(async () =>
            {
                var start = DateTime.Now;
                await Foo();
                Boo().Wait();
                var end = DateTime.Now;
                TimeSpan timeDiff = start - end;
                var readableDiff = string.Format(
                    "{0:D2} hrs, {1:D2} mins, {2:D2} secs",
                    timeDiff.Hours, timeDiff.Minutes, timeDiff.Seconds);
                OutputMessage($"GoDrive() finished. Time ellapsed: {readableDiff}");
            });
        }
    
    
        private Task Foo()
        {
            return Task.Run(async () =>
            {
                //long operation
                OutputMessage($"Running Foo()...");
                await Task.Delay(random.Next(1000, 3000));
                OutputMessage($"Foo() ended!");
            });
        }
    
    
        private Task Boo()
        {
            return Task.Run(async () =>
            {
                OutputMessage($"Running Boo()...");
                await Task.Delay(random.Next(10000, 30000));
                OutputMessage($"Boo() ended!");
            });
        }
    }
    
    public class CarDao
    {
        public List<Car> GetListOfCar()
        {
            var list = new List<Car>();
            for (int i = 1; i <= 10; i++)
                list.Add(new Car { Id = i, Status = Status.Standby });
    
            return list;
        }
    }
    
    public partial class Form1 : Form
    {
        private List<Car> listOfCars;
        private object objInstances = new object();
        public Form1()
        {
            InitializeComponent();
        }
        private Task<Car> GetNextCar()
        {
            return Task.Run(() =>
            {
                lock (objInstances)
                {
                    //Need a logic to prioritize getting cars that have never "run" before
                    var nextCar = listOfCars.Where(x => x.Status != Status.Running).SkipWhile(x => x.Status == Status.Finished).FirstOrDefault();
                    return nextCar;
                }
            });
        }
        private Task<List<Car>> GetInstances(Status statusCar)
        {
            return Task.Run(() =>
            {
                lock (objInstances)
                {
                    return listOfCars.Where(x => x.Status == statusCar).ToList();
                }
            });
        }
    
        private async void button1_Click(object sender, EventArgs e)
        {
            var carDao = new CarDao();
    
            //NumericUpDown value
            var maxSessions = numberOfSessions.Value;
    
            //fixed list of cars
            listOfCars = carDao.GetListOfCar();
    
            //Never stop running
            while (true)
            {
                var runningInstances = GetInstances(Status.Running).Result;
    
                for (int i = runningInstances.Count(); i < maxSessions; i++)
                {
                    var carToRun = GetNextCar().Result;
                    carToRun.Status = Status.Running;
    
                    var carBusiness = new CarBusiness(carToRun, richTextBox);
    
                    Task.Run(() =>
                    {
                        //First thing: StartFullEngine()
                        carBusiness.StartFullEngine().Wait();
                    }).Wait();
    
                    //After started Engine, GoDrive() can run asynchronously.
                    await Task.Run(() =>
                   {
                       carBusiness.GoDrive().Wait();
                       carToRun.Status = Status.Finished;
                   });
                    //Next loop;
                }
                //logic to wait some tasks get done to start again
                runningInstances = GetInstances(Status.Running).Result;
                if (runningInstances.Count() == maxSessions)
                    Task.Delay(20000).Wait();
            }
    
        }
    }
    

    我可以证实,这个问题还不够清楚。如果您可以指定您的期望值,以及这与您的期望值不符的程度,这将有助于我们了解问题的根源,而不必猜测您的意图。@afarley刚刚在预期输出中编辑了问题。您想在这里完成什么还不是很清楚。您的代码中至少有几个突出的问题,例如,您如何通过每次单击按钮来覆盖您的汽车参考列表。@StevePy我认为我缺乏正确的词语来表达自己。我想让它们并行运行。我可以确认这个问题还不够清楚。如果您可以指定您的期望值,以及这与您的期望值不符的程度,这将有助于我们了解问题的根源,而不必猜测您的意图。@afarley刚刚在预期输出中编辑了问题。您想在这里完成什么还不是很清楚。您的代码中至少有几个突出的问题,例如,您如何通过每次单击按钮来覆盖您的汽车参考列表。@StevePy我认为我缺乏正确的词语来表达自己。我想让它们并行运行。