public void EnumerationStressTest()

in rd-net/Test.Lifetimes/Lifetimes/LifetimedListTest.cs [134:230]


    public void EnumerationStressTest()
    {
      var hugeStruct = HugeStruct.Create();

      for (var k = 0; k < 300; k++)
      {
        using var lifetimeDefinition = new LifetimeDefinition();
        var lifetime = lifetimeDefinition.Lifetime;
        
        var list = new LifetimedList<HugeStruct>();
        // ReSharper disable once MethodSupportsCancellation
        var task = Task.Factory.StartNew(() =>
        {
          for (var j = 0; j < 3; j++)
          {
            Task.Factory.StartNew(() =>
            {
              // ReSharper disable once AccessToDisposedClosure
              using (lifetimeDefinition)
              {
                while (lifetime.IsAlive)
                  list.ClearValuesIfNotAlive();
              }
            }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);

            Task.Factory.StartNew(() =>
            {
              // ReSharper disable once AccessToDisposedClosure
              using (lifetimeDefinition)
              {
                while (lifetime.IsAlive)
                {
                  var copy = new List<ValueLifetimed<HugeStruct>>(); // fast enumeration
                  foreach (var lifetimed in list) copy.Add(lifetimed);

                  foreach (var value in copy)
                  {
                    value.Value.AssertValues();
                    if (lifetime.IsNotAlive)
                      return;
                  }
                }
              }
            }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
            
            Task.Factory.StartNew(() =>
            {
              // ReSharper disable once AccessToDisposedClosure
              using (lifetimeDefinition)
              {
                while (lifetime.IsAlive)
                {
                  foreach (var value in list) // slow enumeration
                  {
                    value.Value.AssertValues();
                    if (lifetime.IsNotAlive)
                      return;
                    
                    Thread.Sleep(1);
                  }
                }
              }
            }, TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
          }
        });

        Parallel.Invoke(() =>
        {
          using (lifetimeDefinition)
          {
            for (var i = 0; i < 100; i++)
            {
              using var localDef = lifetime.CreateNested();
              for (var j = 0; j < i; j++)
              {
                list.Add(localDef.Lifetime, hugeStruct);
              }

              if (lifetime.IsNotAlive)
                break;
            }
          }
        }, () =>
        {
          var spinWait = new SpinWait();
          for (var i = 0; i < 100; i++)
          {
            list.AddPriorityItem(lifetime, hugeStruct);
            if (lifetime.IsNotAlive)
              break;
            spinWait.SpinOnce();
          }
        });

        task.Wait();
      }
    }