private DeicingCar SearchFreeCar() { //При поиске свободной машины блокируем поиск для других потоков lock (locker) { DeicingCar car = cars.Values.FirstOrDefault(car => car.Status == Status.Free); //если не нашли свободную машину, начинаем поиск заново while (car == null) { source.CreateToken().Sleep(15); car = cars.Values.FirstOrDefault(car => car.Status == Status.Free); } //иначе прерываем движение на стоянку и ставим статус busy car.Status = Status.Busy; if (carTasks.ContainsKey(car.DeicingCarID)) { if (tokens.TryGetValue(car.DeicingCarID, out var cancellationToken)) { cancellationToken.Cancel(); Task task = carTasks[car.DeicingCarID]; task.Wait(); carTasks.Remove(car.DeicingCarID, out task); } } return(car); } }
private void FillCollections() { for (int i = 0; i < countOfCars; i++) { DeicingCar car = new DeicingCar(i); cars.TryAdd(car.DeicingCarID, car); } }
// ответ private void GoPath(GoToVertexAction action, DeicingCar deicingCar, int destinationVertex) { var path = map.FindShortcut(deicingCar.LocationVertex, destinationVertex); Console.WriteLine($"{deicingCar.DeicingCarID} поедет из {path[0]} в {path[path.Count - 1]}"); for (int i = 0; i < path.Count - 1; i++) { action(deicingCar, path[i + 1]); } }
private void SendVisualizationMessage(DeicingCar deicingCar, int DestinationVertex, int speed) { mqClient.Send <VisualizationMessage>(queueToVisualizer, new VisualizationMessage() { ObjectId = deicingCar.DeicingCarID, DestinationVertex = DestinationVertex, Speed = speed, StartVertex = deicingCar.LocationVertex, Type = Component.Deicing }); }
private void MakeAMove(DeicingCar deicingCar, int DestinationVertex) //just move to vertex { double position = 0; int distance = map.Graph.GetWeightBetweenNearVerties(deicingCar.LocationVertex, DestinationVertex); SendVisualizationMessage(deicingCar, DestinationVertex, DeicingCar.Speed); source.CreateToken().Sleep(distance * 1000 / DeicingCar.Speed); SendVisualizationMessage(deicingCar, DestinationVertex, 0); deicingCar.LocationVertex = DestinationVertex; deicingCar.MotionPermitted = false; }
private void GoToVertexAlone(DeicingCar deicingCar, int DestinationVertex) { WaitForMotionPermission(deicingCar, DestinationVertex); int StartVertex = deicingCar.LocationVertex; MakeAMove(deicingCar, DestinationVertex); mqClient.Send <MotionPermissionRequest>(queueToGroundMotion, //free edge new MotionPermissionRequest() { Action = MotionAction.Free, DestinationVertex = DestinationVertex, Component = Component.Deicing, ObjectId = deicingCar.DeicingCarID, StartVertex = StartVertex }); }
private void GoPathHome(DeicingCar deicingCar, int destinationVertex, CancellationTokenSource cancellationToken) { var path = map.FindShortcut(deicingCar.LocationVertex, destinationVertex); Console.WriteLine($"{deicingCar.DeicingCarID} поедет домой из {path[0]} в {path[path.Count - 1]}"); deicingCar.Status = Status.Free; for (int i = 0; i < path.Count - 1; i++) { if (cancellationToken.IsCancellationRequested) { break; } GoToVertexAlone(deicingCar, path[i + 1]); } }
private void WaitForMotionPermission(DeicingCar deicingCar, int DestinationVertex) { Console.WriteLine($"{deicingCar.DeicingCarID} ждёт разрешения передвинуться в {DestinationVertex}"); mqClient.Send <MotionPermissionRequest>(queueToGroundMotion, //permission request new MotionPermissionRequest() { Action = MotionAction.Occupy, Component = Component.Deicing, DestinationVertex = DestinationVertex, ObjectId = deicingCar.DeicingCarID, StartVertex = deicingCar.LocationVertex }); while (!deicingCar.MotionPermitted) //check if deicingcar can go { source.CreateToken().Sleep(5); } }
private void MessageFromGroundService() { mqClient.SubscribeTo <ServiceCommand>(queueFromGroundService, (sc) => { Console.WriteLine(DateTime.Now + " " + Component.Deicing + " Получил сообщение от СНО"); DeicingCar car = SearchFreeCar(); Console.WriteLine($"нашли свободную машину {car.DeicingCarID}"); Task t = new Task(() => { //приехать к самолёту GoPath(GoToVertexAlone, car, sc.PlaneLocationVertex); Console.WriteLine($"{DateTime.Now} {car.DeicingCarID} приехала к самолёту"); //чистим самолёт от льда WorkWithPlane(sc.PlaneId); Console.WriteLine($"{DateTime.Now} {car.DeicingCarID} почистила самолёт"); ServiceCompletionMessage deicingCompletion = new ServiceCompletionMessage() { PlaneId = sc.PlaneId, Component = Component.Deicing }; mqClient.Send <ServiceCompletionMessage>(queueToGroundService, deicingCompletion); Console.WriteLine($"{DateTime.Now} {car.DeicingCarID} отправила сообщение СНО"); var source = new CancellationTokenSource(); //adds token and remove it after went home/new cmd tokens.TryAdd(car.DeicingCarID, source); //уезжаем на стоянку GoPathHome(car, RandomHomeVertex.GetHomeVertex(), tokens[car.DeicingCarID]); if (!tokens[car.DeicingCarID].IsCancellationRequested) //если не было отмены пути домой { Console.WriteLine($"{DateTime.Now} {car.DeicingCarID} приехала домой"); } tokens.Remove(car.DeicingCarID, out source); }); carTasks.TryAdd(car.DeicingCarID, t); t.Start(); }); }