简体   繁体   English

使用C#异步等待进行负载测试

[英]Load Test using C# Async Await

I am creating a console program, which can test read / write to a Cache by simulating multiple clients, and have written following code. 我正在创建一个控制台程序,该程序可以通过模拟多个客户端来测试对Cache的读/写,并编写了以下代码。 Please help me understand: 请帮助我了解:

  • Is it correct way to achieve the multi client simulation 是实现多客户端模拟的正确方法
  • What can I do more to make it a genuine load test 我可以做些什么来使其成为真正的负载测试
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);
}

Adjusted your code slightly to see how many threads we have at a particular time. 略微调整您的代码以查看特定时间我们有多少个线程。

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
    );
}

The result is: inside a virtual machine I have from 2 to 10 threads running simultaneously if I don't use the hint. 结果是:在虚拟机内部,如果不使用提示,则我将同时运行2至10个线程。 With the hint — up to 100. And on real machine I can see 1000 threads at once. 带有提示-最多100个。在实际计算机上,我可以一次看到1000个线程。 Process explorer confirms this. Process Explorer证实了这一点。 Some details on the hint that would be helpful. 提示上的一些细节可能会有所帮助。

If it is very busy, then apparently your clients have to wait a while before their requests are serviced. 如果很忙,那么显然您的客户必须等待一段时间才能为他们的请求提供服务。 Your program does not measure this, because your stopwatch starts running when the service request starts. 您的程序无法衡量这一点,因为秒表在服务请求启动时开始运行。

If you also want to measure what happen with the average time before a request is finished, you should start your stopwatch when the request is made, not when the request is serviced. 如果您还想衡量请求完成前的平均时间,应该在提出请求时而不是在为请求提供服务时启动秒表。

Your program takes only threads from the thread pool. 您的程序仅从线程池中获取线程。 If you start more tasks then there are threads, some tasks will have to wait before TestAsync starts running. 如果您开始执行更多任务,则有线程存在,某些任务将必须等待TestAsync开始运行。 This wait time would be measured if you remember the time Task.Run is called. 如果您还记得调用Task.Run的时间,那么将计算该等待时间。

Besides the flaw in time measurements, how many service requests do you expect simultaneously? 除了时间测量方面的缺陷外,您还期望同时进行几个服务请求吗? Are there enough free threads in your thread pool to simulate this? 您的线程池中是否有足够的可用线程来模拟这一点? If you expect about 50 service requests at the same time, and the size of your thread pool is only 20 threads, then you'll never run 50 service requests at the same time. 如果您希望同时看到大约50个服务请求,并且线程池的大小只有20个线程,那么您将永远不会同时运行50个服务请求。 Vice versa: if your thread pool is way bigger than your number of expected simultaneous service requests, then you'll measure longer times than are actual the case. 反之亦然:如果您的线程池比预期的同时服务请求数大得多,那么测量的时间将比实际情况更长。

Consider changing the number of threads in your thread pool, and make sure no one else uses any threads of the pool. 考虑更改线程池中的线程数,并确保没有其他人使用该池中的任何线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM