隐藏

C#高并发测试代码

发布:2021/11/6 11:02:08作者:管理员 来源:本站 浏览次数:933



最近在研究高并发下,如何准确测得方法执行时间,我想到的办法是这样的:可以这样比喻3000名运动员再跑马拉松,起点还不同,突然跑道上到了一棵树,这棵树又恰好能拦住所有人,待所有人都跑到这颗树前的时候,树就挪开了,而此时运动员之间的距离就是最小的。

而我运用lock机制,达到这种效果,只可惜lock似乎对阻塞线程的队列有一定限制,队列满了就一定要放出一个,否则就会报出异常,而且队列大小似乎是2000~3000线程来着的。

代码如下:


   using System;

   using System.Collections.Generic;

   using System.Threading;

   

   namespace Test

   {

   

       //测试并发时间委托

       public delegate void ConcurrencyTest();

       /// <summary>

       /// 高并发测试类

       /// </summary>

       public static class HighConcurrencyTest

       {

   

           /// <summary>

           /// 测试高并发下单个委托的执行时间

           /// </summary>

           /// <param name="count">并发计数</param>

           /// <param name="cTest">委托</param>

           /// <param name="sizeThread">一个线程执行的估计时间,可以估计的大些,默认是6毫秒</param>

           /// <returns></returns>

           public static double StartTest(int count,ConcurrencyTest cTest,int sizeThread=6)

           {

               #region 为保证之后取得的时间准确度,初始化

               ConcurrentLock cLock = new ConcurrentLock();

               ConcurrentLock autoLock = new ConcurrentLock();

               GC.Collect();

               GC.Collect();

               GC.Collect();

               GC.Collect();

               #endregion

   

               #region 测算1亿次if时间,并按比例计算出时间差

               int max = ((count + 1) * count) / 2;//if被操作的总次数

               double stime = new TimeSpan(DateTime.Now.Ticks).TotalMilliseconds;

               for (int i = 0; i < 100000000; i++)

               {

                   if (cLock.EndTime == -1)

                   {

                   }

               }

               double etime = new TimeSpan(DateTime.Now.Ticks).TotalMilliseconds;

               double ifSpan = ((etime - stime) / 100000000d) * max;

               #endregion

   

               #region 清理内存使用,再初始化

               GC.Collect();

               GC.Collect();

               GC.Collect();

               GC.Collect();

               Thread.Sleep(3000);

               #endregion

   

               #region 执行,执行原理如下,因为线程开启的时间,各个线程之间存在时间差,现在采取一种办法,使其时间差只是一个if判断

               List<Thread> threads = new List<Thread>();

               int current = 0;

               for (int i = 0; i < count; i++)

               {

                   var thread = new Thread(() =>

                   {

                       //开始,挡路所有线程

                       lock (autoLock)

                       {

                           if (autoLock.StartTime == -1)

                           {

                               autoLock.StartTime = new TimeSpan(DateTime.Now.Ticks).TotalMilliseconds;

                               Thread.Sleep(sizeThread * count);

                           }

                       }

                       //释放挡路的路牌

                       #region 委托执行

                       cTest();

                       #endregion

                       //结束使用原子计数器

                       Interlocked.Increment(ref current);

                       if (current >= count)

                       {

                           //此时所有线程都运行完该委托

                           autoLock.EndTime = new TimeSpan(DateTime.Now.Ticks).TotalMilliseconds;

                       }

                   });

                   thread.IsBackground = true;

                   thread.SetApartmentState(ApartmentState.MTA);

                   threads.Add(thread);

               }

               foreach (var t in threads)

               {

                   t.Start();

               }

               foreach (var t in threads)

               {

                   t.Join();

               }

               #endregion

   

               return (double)(autoLock.EndTime - autoLock.StartTime - sizeThread * count - ifSpan) / (double)count;

           }

       }

   

       class ConcurrentLock

       {

           public double StartTime { get; set; }

   

           public double EndTime { get; set; }

   

           public ConcurrentLock()

           {

               StartTime = -1;

               EndTime = -1;

           }

   

           public void Reset()

           {

               StartTime = -1;

               EndTime = -1;

           }

       }

   }




转载于:https://www.cnblogs.com/zmx-mk/p/MemberConcurrentTest.html