public override TestResults Execute()
        {
            Status = TestStatus.Started;

            //Linux
            file.EmptyMemCacheAfterWritesIfNeeded();

            ValidateAndInitParams();
            GeneratePositionsPlan();

            var results = new TestResults(this);

            byte[] data = null;

            try
            {
                data = InitBuffer();
            }
            catch
            {
                NotEnoughMemUpdate(results, 0);
                return(results);
            }

            if (cachePurger != null)
            {
                Status = TestStatus.PurgingMemCache;
                cachePurger.Purge();
            }

            var sw = new Stopwatch();

            int  prevPercent = -1;
            int  curPercent  = -1;
            long currOffset  = 0;

            var i = 0;

            var elapsed = new Stopwatch();

            elapsed.Start();

            Status = TestStatus.Running;

            while (i < positionsPlan.Length + 1)
            {
                if (breakCalled)
                {
                    return(results);
                }

                currOffset = positionsPlan[i];

                i++; // easier to calculate progress in precent when starting with 1

                DoOperation(data, sw, currOffset, i);

                results.AddTroughputMbs(blockSize, currOffset, sw);

                curPercent = Math.Min(
                    100,
                    Math.Max(
                        (int)(elapsed.ElapsedMilliseconds / 10 / maxTestTime),
                        curPercent = (int)(i * 100 / (double)positionsPlan.Length)
                        )
                    );

                if (curPercent > prevPercent)
                {
                    Update(curPercent, results.GetLatest5AvgResult(), results: results);
                    prevPercent = curPercent;

                    if (curPercent == 100)
                    {
                        break;
                    }
                }
            }

            elapsed.Stop();
            results.TotalTimeMs = elapsed.ElapsedMilliseconds;

            FinalUpdate(results, elapsed.ElapsedMilliseconds);

            //if (cachePurger != null)
            //{
            //    cachePurger.Release();
            //}

            return(results);
        }
        public override TestResults Execute()
        {
            Status = TestStatus.Started;

            //Linux
            file.EmptyMemCacheAfterWritesIfNeeded();

            var results = new TestResults(this);

            byte[] data = null;

            try
            {
                data = InitBuffer();
            }
            catch
            {
                NotEnoughMemUpdate(results, 0);
                return(results);
            }

            if (cachePurger != null)
            {
                Status = TestStatus.PurgingMemCache;
                cachePurger.Purge();
            }

            var sw = new Stopwatch();

            int prevPercent = -1;
            int curPercent  = -1;

            fileStream.Seek(0, SeekOrigin.Begin);

            RestartElapsed();

            //var sw2 = new Stopwatch();

            var warmUpBlocks = warmUp ? (int)Math.Ceiling(totalBlocks * warmUpBlocksPercentFromTotal) : 0;

            if (warmUp)
            {
                Status = TestStatus.WarmigUp;
            }
            else
            {
                Status = TestStatus.Running;
            }
            for (var i = 1 - warmUpBlocks; i < totalBlocks + 1; i++)
            {
                //sw2.Restart();

                if (breakCalled)
                {
                    return(results);
                }

                DoOperation(data, sw);

                if (i == 0) // final warm up block
                {
                    Status = TestStatus.Running;
                    fileStream.Seek(0, SeekOrigin.Begin);
                }

                if (i > 0) // not warm up blocks
                {
                    results.AddTroughputMbs(blockSize, fileStream.Position - blockSize, sw);

                    curPercent = (int)(i * 100 / totalBlocks);
                    if (curPercent > prevPercent)
                    {
                        Update(curPercent, results.GetLatest5AvgResult(), results: results);
                        prevPercent = curPercent;
                    }
                }

                //sw2.Stop();

                //var swMs = ((double)sw.ElapsedTicks / Stopwatch.Frequency)*1000 ;
                //var sw2Ms = ((double)sw2.ElapsedTicks / Stopwatch.Frequency)*1000 ;

                //Debug.WriteLine("Block: " + i +
                //                "; sw(ms): " + swMs +
                //                "; sw2(ms): " + sw2Ms +
                //                "sw/sw2: " + swMs/sw2Ms);
            }

            results.TotalTimeMs = StopElapsed();

            FinalUpdate(results, ElapsedMs);

            //if (cachePurger != null)
            //{
            //    cachePurger.Release();
            //}

            TestCompleted();

            return(results);
        }