我怎样才能确保我的测试开始并且 运行 正确?
How can I make sure my tests start and run correctly?
我正在决定是使用 TPL 数据流块还是某种 producer/consumer 方法来进行这些测试。生成任务列表将非常快,因为每个任务只是一个包含测试参数列表的字符串,例如设置参数、所需的测量和测量之间的时间。此任务列表将只是通过 GUI 加载的文件(每个测试 1 个文件)。
当测试开始时,它应该立即开始。测试可能会非常长且非常不同步,因为一个动作可能需要几秒或几十分钟(例如加热设备),然后是需要几秒(或几分钟)的测量,然后是很长一段时间的不动作( 24 小时),然后再次重复测试。
我最多可以同时进行 16 项测试 运行ning,但我需要能够随时取消其中任何一项测试的灵活性。我还需要能够随时添加新测试(即尝试描绘 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 秒任务中的一个或多个之前被阻止。我也不确定如何识别每个操作块以取消特定的操作块。
您没有获得预期性能的原因是您的工作负载是同步的并且阻塞了线程池线程。您是否希望在您的生产环境中实际拥有同步(阻塞)工作负载?如果是,您可以在启动 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 秒左右。
我正在决定是使用 TPL 数据流块还是某种 producer/consumer 方法来进行这些测试。生成任务列表将非常快,因为每个任务只是一个包含测试参数列表的字符串,例如设置参数、所需的测量和测量之间的时间。此任务列表将只是通过 GUI 加载的文件(每个测试 1 个文件)。
当测试开始时,它应该立即开始。测试可能会非常长且非常不同步,因为一个动作可能需要几秒或几十分钟(例如加热设备),然后是需要几秒(或几分钟)的测量,然后是很长一段时间的不动作( 24 小时),然后再次重复测试。
我最多可以同时进行 16 项测试 运行ning,但我需要能够随时取消其中任何一项测试的灵活性。我还需要能够随时添加新测试(即尝试描绘 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 秒任务中的一个或多个之前被阻止。我也不确定如何识别每个操作块以取消特定的操作块。
您没有获得预期性能的原因是您的工作负载是同步的并且阻塞了线程池线程。您是否希望在您的生产环境中实际拥有同步(阻塞)工作负载?如果是,您可以在启动 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 秒左右。