使用控制台应用程序的算术运算

时间:2017-02-07 06:39:37

标签: c# multithreading

我正在尝试使用简单的算术运算创建一个应用程序来记录每台机器所经过的时间。

使用控制台应用程序,使用循环次数参数和要与下面代码一起使用的线程:

public static Int64 IterationCount { get; set; }

static void Main(string[] args)
{
    int iterations = int.Parse(args[0]);
    int threads = int.Parse(args[1]);

    IterationCount = iterations * 1000000000;

    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < threads; i++)
    {
        Task.Factory.StartNew(() => Calculate());
        Task.WaitAll();
    }   
    sw.Stop();

    Console.WriteLine("Elapsed={0}", sw.Elapsed);
}

我的Calculate方法:

private static void Calculate()
{
    for (int i = 0; i < IterationCount; i++)
    {
        a = 1 + 2;
        b = 1 - 2;
        c = 1 * 2;
        a = 1 / 2;
    }
}

现在我认为这不起作用,因为我输入 10次迭代(我将第一个参数乘以10亿次:10 * 1,000,000,000) 4个线程时的经过时间的结果是:

00:00:00:0119747

我错过了什么?

2 个答案:

答案 0 :(得分:1)

原来我的评论是准确的。如果我将Calculate方法的内容复制到Visual Studio中:

private static void Calculate()
{
    for (int i = 0; i < IterationCount; i++)
    {
        a = 1 + 2;
        b = 1 - 2;
        c = 1 * 2;
        d = 1 / 2;
    }
}

编译后,生成的C#代码如下所示:

private static void Calculate()
{
    for (int i = 0; i < Program.IterationCount; i++)
    {
        Program.a = 3;
        Program.b = -1;
        Program.c = 2;
        Program.d = 0;
    }
}

相反,您必须将其中一个常量变为变量:

private static void Calculate()
{
    int x = 1;
    for (int i = 0; i < IterationCount; i++)
    {
        a = x + 2;
        b = x - 2;
        c = x * 2;
        d = x / 2;
    }
}

此代码变为:

private static void Calculate()
{
    int x = 1;
    for (int i = 0; i < Program.IterationCount; i++)
    {
        Program.a = x + 2;
        Program.b = x - 2;
        Program.c = x * 2;
        Program.d = x / 2;
    }
}

答案 1 :(得分:1)

您对Task.WaitAll()的呼叫无效,因为该功能的签名是

public static void WaitAll(params Task[] tasks)

您可以看到,您可以提供等待的Tasks变量计数,并且您可以在没有任务的情况下调用此函数;所以它不会等待。

如果您通过以下代码替换代码,您将看到效果。

Task[] tasks = new Task[threads];
for (int i = 0; i < threads; i++)
{
    tasks[i] = Task.Factory.StartNew(() => Calculate());
}
Task.WaitAll(tasks);