使用 C# Async Await 进行负载测试

Load Test using C# Async Await

我正在创建一个控制台程序,它可以通过模拟多个客户端来测试对缓存的读/写,并编写了以下代码。请帮助我理解:

void Main()
{

    List<Task<long>> taskList = new List<Task<long>>();

    for (int i = 0; i < 500; i++)
    {
      taskList.Add(TestAsync());
    }

    Task.WaitAll(taskList.ToArray());

    long averageTime  = taskList.Average(t => t.Result);

}

public static async Task<long> TestAsync()
{
    // Returns the total time taken using Stop Watch in the same module
    return await Task.Factory.StartNew(() => // Call Cache Read / Write);
}

稍微调整了您的代码以查看我们在特定时间有多少个线程。

static volatile int currentExecutionCount = 0;

static void Main(string[] args)
{
    List<Task<long>> taskList = new List<Task<long>>();
    var timer = new Timer(Print, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));

    for (int i = 0; i < 1000; i++)
    {
        taskList.Add(DoMagic());
    }

    Task.WaitAll(taskList.ToArray());

    timer.Change(Timeout.Infinite, Timeout.Infinite);
    timer = null;

    //to check that we have all the threads executed
    Console.WriteLine("Done " + taskList.Sum(t => t.Result));
    Console.ReadLine();
}

static void Print(object state)
{
    Console.WriteLine(currentExecutionCount);
}

static async Task<long> DoMagic()
{
    return await Task.Factory.StartNew(() =>
    {
        Interlocked.Increment(ref currentExecutionCount);
        //place your code here
        Thread.Sleep(TimeSpan.FromMilliseconds(1000));
        Interlocked.Decrement(ref currentExecutionCount);
        return 4;
    }
    //this thing should give a hint to scheduller to use new threads and not scheduled
    , TaskCreationOptions.LongRunning
    );
}

结果是:如果我不使用提示,在虚拟机中我同时拥有 2 到 10 个线程 运行。有了提示——最多 100 个。在真机上我可以同时看到 1000 个线程。 Process Explorer 证实了这一点。 hint 的一些详细信息会有所帮助。

如果它很忙,那么显然您的客户必须等待一段时间才能满足他们的请求。您的程序不会对此进行测量,因为您的秒表会在服务请求启动时启动 运行ning。

如果您还想测量请求完成前的平均时间发生了什么,您应该在请求发出时启动秒表,而不是在请求得到服务时。

您的程序只从线程池中获取线程。如果您启动更多任务然后有线程,一些任务将不得不等待 TestAsync 启动 运行ning。如果您记得调用 Task.Run 的时间,就会计算出此等待时间。

除了时间测量上的缺陷外,您预计同时有多少服务请求?你的线程池中是否有足够的空闲线程来模拟这个?如果您期望同时有大约 50 个服务请求,而您的线程池的大小只有 20 个线程,那么您永远不会 运行 同时有 50 个服务请求。反之亦然:如果您的线程池比预期的同时服务请求数量大得多,那么您测量的时间将比实际情况长。

考虑更改线程池中的线程数,并确保没有其他人使用池中的任何线程。