我如何确保我的测试正确启动和运行?

问题描述 投票:0回答:1

我正在确定是使用TPL数据流模块还是某种生产者/消费者方法进行这些测试。生成任务列表将非常快,因为每个任务只是一个字符串,其中包含测试参数列表,例如设置参数,所需的测量以及测量之间的时间。此任务列表将只是通过GUI加载的文件(每个测试1个文件)。

开始测试时,应立即开始。测试可能非常长且非常异步,因为一个操作可能需要几秒钟或数十分钟(例如,加热设备),然后进行一次测量需要几秒钟(或几分钟),然后长时间不进行操作( 24小时),然后再次重复测试。

我最多可以同时运行16个测试,但是我需要能够随时取消任何一个测试的灵活性。我还需要能够随时添加新测试(例如,尝试对16台设备进行测试,或者在一个月中跨月添加和删除各个测试设备的时间跨度)。

((Visual C#)我尝试了此示例代码来处理TPL数据流,在该代码中,我告诉它同时运行32个简单任务。每个任务仅需5秒的延迟即可模拟工作。由于完成任务所花的时间为15秒,因此似乎正在并行处理任务。我认为由于调度和任何其他开销,所有32个任务都没有在5秒内完成,但是我有点担心某些任务可能被阻止。

    class Program
    {
    // Performs several computations by using dataflow and returns the elapsed
    // time required to perform the computations.
    static TimeSpan TimeDataflowComputations(int messageCount)
    {
    // Create an ActionBlock<int> that performs some work.
    var workerBlock = new ActionBlock<int>(
        // Simulate work by suspending the current thread.

        millisecondsTimeout => Thread.Sleep(millisecondsTimeout),
       // Specify a maximum degree of parallelism.
       new ExecutionDataflowBlockOptions
       {
           MaxDegreeOfParallelism = messageCount
       });


    // Compute the time that it takes for several messages to 
    // flow through the dataflow block.

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();

    for (int i = 0; i < messageCount; i++)
    {
        workerBlock.Post(5000);  // simulated work: a delay of 5 seconds.
    }
    workerBlock.Complete();

    // Wait for all messages to propagate through the network.
    workerBlock.Completion.Wait();

    // Stop the timer and return the elapsed number of milliseconds.
    stopwatch.Stop();
    return stopwatch.Elapsed;
    }



    static void Main(string[] args)
    {

    int messageCount = 32; 

    TimeSpan elapsed;

    // set processors  maximum degree of parallelism. This causes
    // multiple messages to be processed in parallel.

    Console.WriteLine("START:\r\n");
    elapsed = TimeDataflowComputations(messageCount);
    Console.WriteLine("message count = {1}; " +
       "elapsed time = {2}ms.", messageCount, 
        (int)elapsed.TotalMilliseconds);

    Console.ReadLine();
    } 
    }

该演示似乎可以正常工作,但是我不确定在完成5秒任务中的一项或多项之前是否阻止了任何任务。我也不确定如何取消每个动作块以取消特定动作。

c# task-parallel-library producer-consumer dataflow
1个回答
2
投票

之所以无法获得预期的性能,是因为您的工作负载是同步的,并且阻塞了线程池线程。您是否期望生产环境中实际有同步(阻塞)工作负载?如果是,则可以尝试在启动TPL数据流管道之前提高可用线程的ThreadPool储备:

ThreadPool.SetMinThreads(workerThreads: 100, completionPortThreads: 100);

如果您的实际工作负载是异步的,那么最好使用Task.Delay而不是Thread.Sleep对其进行仿真。

var workerBlock = new ActionBlock<int>(async millisecondsTimeout =>
{
    await Task.Delay(millisecondsTimeout);
}, new ExecutionDataflowBlockOptions
{
    MaxDegreeOfParallelism = messageCount
});

我没有测试它,但是使用这两种方法,您应该在5秒钟左右获得完成时间。

© www.soinside.com 2019 - 2024. All rights reserved.