如何使用线程将项添加到列表中

时间:2018-05-12 19:01:31

标签: c# multithreading list dictionary

我有一份预订清单,但有些预订有冲突(他们在同一天预订同一房间)。为了解决这个问题,我想创建一个没有冲突的新列表。我只能更改房间号,而不能更改预订日期,所以我用以下方法更改:

        public List<Reservation> ResolveConflicts()
        {
            var groupedReservationByDate = _reservations.GroupBy(reservation => reservation.CheckInDate);
            var resolvedReservations = new List<Reservation>();
            foreach (var reservations in groupedReservationByDate)
            {
                foreach (var currentReservation in reservations)
                {
                    var nextReservations = reservations.Skip(reservations.ToList().IndexOf(currentReservation) + 1)
                        .ToList();
                    foreach (var nextReservation in nextReservations)
                    {
                        if (currentReservation.RoomNumber == nextReservation.RoomNumber)
                        {
                            var thread = new Thread(() => ChangeRoomNumber(reservations, currentReservation));
                            thread.Start();
                        }
                    }

                    resolvedReservations.Add(currentReservation);
                }
            }

            return resolvedReservations;
        }

        private void ChangeRoomNumber(IEnumerable<Reservation> reservations, Reservation currentReservation)
        {
            var roomNumber = GetRoomNumber();
            foreach (var reservation in reservations)
            {
                if (roomNumber == reservation.RoomNumber)
                    roomNumber = GetRoomNumber();
            }

            currentReservation.RoomNumber = roomNumber ;
        }

        private int GetRoomNumber()
        {
            var randomNumber = new Random();
            return randomNumber.Next(1, _reservations.MaxBy(reservation => reservation.RoomNumber).RoomNumber);
        }

当我用线程执行此操作时,我得到一种正确的列表,但是不正确,返回的列表应该没有冲突。当我使用Thread.Sleep(1000)Console output with reservation conflicts using a thread时会产生相同的输出。

如果我不使用线程,则返回的列表完全不正确,因为同一个房间存在很多冲突Console output with reservation conflicts without using a thread

我认为线程存在问题,算法是正确的,或者至少我希望是正确的。

1 个答案:

答案 0 :(得分:0)

感谢凯文,我已经解决了这个问题:

  

如果没有看得太远,您的ChangeRoomNumber方法就会被破坏。您将获得一个随机房间号码,然后迭代预订并生成一个新房间号码(如果已分配了前一个号码)。这是错误的,如果您生成新号码,则必须再次检查所有预订 - @Kevin Gosse

解决方案是:

private void ChangeRoomNumber(List<Reservation> reservations, Reservation currentReservation)
{
    while (IsConflict(reservations, currentReservation))
        currentReservation.RoomNumber = GetRoomNumber();
}

private bool IsConflict(IEnumerable<Reservation> reservations, Reservation currentReservation)
{
    return reservations.Any(reservation =>
        !ReferenceEquals(reservation, currentReservation) &&
        reservation.RoomNumber == currentReservation.RoomNumber);
}