我在一个数组中有多个任务,用于计算给定范围内的素数。要进行任务与线程性能的比较,我想在任务中使用线程,然后检查性能统计信息。
线程如何与任务一起使用,到目前为止,这就是我所做的:
public Form1()
{
InitializeComponent();
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();
this.numericUpDown1.Maximum = int.MaxValue;
}
private void btnCalculate_Click(object sender, EventArgs e)
{
//get the lower and upper bounds for prime range
int lower = int.Parse(this.numericUpDown1.Value.ToString());
int upper = 0 ;
//get the time in milliseconds for task deadline
int taskDeadline = int.Parse(this.time.Text);
//determine tasks completed
int tasksCompleted = 0;
Random random = new Random();
for (int taskCount = 1; taskCount <= 1; ++taskCount)
{
int taskArraySize = taskCount * 100;
Task[] taskArray = new Task[taskArraySize];
this.txtNumOfPrimes.Text += "Performing test for " +
taskArraySize.ToString() +
" tasks" +
Environment.NewLine +
Environment.NewLine;
for (int i = 0; i < taskArray.Length; i++)
{
upper = random.Next(5, 10);
taskArray[i] = new Task(() => getPrimesInRange(lower, upper));
taskArray[i].Start();
bool timeout = taskArray[i].Wait(taskDeadline);
if (!timeout)
{
// If it hasn't finished at timeout display message
this.txtNumOfPrimes.Text +=
"Message to User: Task not completed, Status=> " +
taskArray[i].Status.ToString() +
Environment.NewLine;
}
else
{
this.txtNumOfPrimes.Text += "Task completed in timeout " +
", CPU usage: " + this.getCurrentCpuUsage() +
", RAM usage: " +
this.getAvailableRAM() +
Environment.NewLine;
tasksCompleted++;
}
}
}
this.txtNumOfPrimes.Text += Environment.NewLine;
this.txtNumOfPrimes.Text +=
"Tasks Completed: " +
tasksCompleted.ToString() +
Environment.NewLine;
}
答案 0 :(得分:1)
任务的重点是“simplifying the process of adding parallelism and concurrency to applications”。确实(来自http://msdn.microsoft.com/en-us/library/dd537609):
在幕后,任务排队到ThreadPool,一直是 增强了算法(如爬山),确定和 调整到最大化吞吐量的线程数。这使得 任务相对轻量级,你可以创建其中的许多 实现细粒度并行。为了补充这一点,广为人知 工作窃取算法用于提供负载平衡。
简而言之,任务使线程工作没有太多的麻烦和腿部工作。
要比较两者,请考虑使用Parrallel.ForEach执行任务。例如:
public class PrimeRange
{
public int Start;
public int Snd;
}
List<PrimeRange> primes = new []
{
new PrimeRange{Start = 0, End = 1000},
new PrimeRange{Start = 1001, End = 2000}
// An so on
};
Parallel.ForEach(primes, x => CalculatePrimes(x, OnResult())));
其中CalculatePrimes
是一种方法,在计算素数时需要PrimeRange
和委托调用。 Parraler.ForEach将为每个素数元素启动一个任务,并在其上运行CalculatePrimes()
并为您处理线程分配和调度。
要将它与线程进行比较,请使用以下内容:
List<Thread> threads = new List<Thread>();
foreach(PrimeRange primeRange in primes)
{
threads = new Thread(CalculatePrimes).Start(x);
}
foreach(var thread in threads)
{
thread.Join();
}
其中CalculatePrimes还需要存储结果(或类似的东西)。有关等待运行线程的更多信息,请参阅C# Waiting for multiple threads to finish。
您可以使用StopWatch来计算结果。