Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使基本多线程循环返回正确的值_C#_Multithreading - Fatal编程技术网

C#使基本多线程循环返回正确的值

C#使基本多线程循环返回正确的值,c#,multithreading,C#,Multithreading,首先,我是C#新手,这是我编写的第一个使用线程的程序。对不起,如果有点基础的话 这是我的应用程序: class Program { static void AddNumbers() { int count = 0; for (int counter = 0; counter < 90000000; counter++) { count += counter; } }

首先,我是C#新手,这是我编写的第一个使用线程的程序。对不起,如果有点基础的话

这是我的应用程序:

    class Program
{
    static void AddNumbers()
    {
        int count = 0; 

        for (int counter = 0; counter < 90000000; counter++)
        {
            count += counter;
        }
    }

    static void Main()
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();

        for (int i = 0; i < 50; i++)
        {
            // Non-threaded
            //AddNumbers();
            //Console.WriteLine((i + 1).ToString());

            // Threaded
            new Thread(() =>
            {
                //Thread.CurrentThread.IsBackground = true;

                AddNumbers();
                Thread.Sleep(1000);

                Console.WriteLine((i + 1).ToString());
            }).Start();
        }

        stopwatch.Stop();
        Console.WriteLine("Time elapsed: {0:hh\\:mm\\:ss}", stopwatch.Elapsed);

        Console.ReadLine();
    }
}
类程序
{
静态void AddNumbers()
{
整数计数=0;
用于(整数计数器=0;计数器<90000000;计数器++)
{
计数+=计数器;
}
}
静态void Main()
{
秒表秒表=新秒表();
秒表。开始();
对于(int i=0;i<50;i++)
{
//无螺纹
//addnumber();
//Console.WriteLine((i+1.ToString());
//螺纹
新线程(()=>
{
//Thread.CurrentThread.IsBackground=true;
addnumber();
睡眠(1000);
Console.WriteLine((i+1.ToString());
}).Start();
}
秒表;
WriteLine(“经过的时间:{0:hh\\\:mm\\:ss}”,stopwatch.appeased);
Console.ReadLine();
}
}
它简单地循环
i
次,每次添加一组数字。当我运行
AddNumbers()
版本非多线程时,它会正确显示
1、2、3…
等,但当我运行它多线程时,它会返回相同的索引2-3次,跳过一些,并在所有线程执行之前返回秒表值

有人能帮我找出我的错误所在,最重要的是澄清我对C#中线程如何工作的想法吗?谢谢

当我非多线程运行AddNumbers()版本时,它会正确地显示1、2、3。。。等等,但当我以多线程方式运行它时,它会返回相同的索引2-3次,跳过一些

这是因为捕获了
i
,但在外部循环中发生了更改

请在此处阅读更多信息:


为了使其正常工作,您需要保存本地副本:

for (int i = 0; i < 50; i++)
{
    // Non-threaded
    //AddNumbers();
    //Console.WriteLine((i + 1).ToString());

    // Threaded
    int iCopy = i;
    new Thread(() =>
    {
        //Thread.CurrentThread.IsBackground = true;

        AddNumbers();
        Thread.Sleep(1000);

        Console.WriteLine((iCopy + 1).ToString());
    }).Start();
}
在此处阅读有关等待线程完成的更多信息:

在第三方物流发明之前,人们就是这样做的。
现在,一般规则不是使用
线程
,而是使用
任务
并行

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

Task[] tasks = new Task[50];
for (int i = 0; i < 50; i++)
{
    int iCopy = i;
    tasks[i] = Task.Run(() => {
        AddNumbers();
        Thread.Sleep(1000);
        Console.WriteLine((iCopy + 1).ToString());
    });
} 

Task.WaitAll(tasks);
秒表秒表=新秒表();
秒表。开始();
任务[]任务=新任务[50];
对于(int i=0;i<50;i++)
{
int-iCopy=i;
任务[i]=任务。运行(()=>{
addnumber();
睡眠(1000);
Console.WriteLine((iCopy+1.ToString());
});
} 
Task.WaitAll(任务);

谢谢你。我将
Task.StartNew
更改为
Task.Run
,效果很好。我很感激你的解释和帮助。@KyleCarlson我很高兴这对你有帮助。哦,是的,的确如此。它要么是
Task.Factory.StartNew
要么是
Task.Run
,两者都是同义词,我把它们混在了一起:D
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();

Task[] tasks = new Task[50];
for (int i = 0; i < 50; i++)
{
    int iCopy = i;
    tasks[i] = Task.Run(() => {
        AddNumbers();
        Thread.Sleep(1000);
        Console.WriteLine((iCopy + 1).ToString());
    });
} 

Task.WaitAll(tasks);