C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

时间:2022-07-22 02:23:08

        private int i1 = 0, i2 = 0, i3 = 0;    
        private void button1_Click(object sender, EventArgs e)
        {
            Task[] tasks = new Task[3];
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }
            Task.WaitAll(tasks);
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3));
        }

        private void setIv(int s, int n)
        {
            switch (s)
            {
                case 3:
                    {
                        for (int i = 0; i < 10000; i++)
                        { }
                        i1 = n;
                        break;
                    }
                case 4:
                    {
                        for (int i = 0; i < 50000; i++)
                        { }
                        i2 = n;
                        break;
                    }
                case 5:
                    {
                        for (int i = 0; i < 100000; i++)
                        { }
                        i3 = n;
                        break;
                    }
            }
        }

        public void testTask(int n)
        {
            //TODO: Add your code here
            switch (n)
            {
                case 0:
                    {
                        setIv(3, 1);
                        break;
                    }
                case 1:
                    {
                        setIv(4, 2);
                        break;
                    }
                case 2:
                    {
                        setIv(5, 3);
                        break;
                    }
            }
        }

21 个解决方案

#1


目前的情况是,第一下单击,出现0,0,0  再等一下1,0,0然后一次1,2,3
而我想要的是,直接卡死在这里,直到拿到1,2,3 
难道要用死循环等待吗
请各位前辈指点迷津

#2


await Task.WhenAll()

#3


你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

#4


例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

#5


引用 2 楼 starfd 的回复:
await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

#6


引用 3 楼 starfd 的回复:
你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

#7


引用 4 楼 sp1234 的回复:
例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

前辈回复给我的内容,没看明白,想前辈这么写,应该是有三个task,九个新线程

#8


引用 6 楼 chenggaohua 的回复:
Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

#9


引用 7 楼 chenggaohua 的回复:
Quote: 引用 4 楼 sp1234 的回复:

例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

前辈回复给我的内容,没看明白,想前辈这么写,应该是有三个task,九个新线程

很明显,lambda表达式捕获的是全局静态的变量,,,,,,,

#10


            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。

#11


实测只有  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识一种结果
并不存在楼主描述的现象

#12


引用 5 楼 chenggaohua 的回复:
Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

#13


引用 4 楼 sp1234 的回复:
例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

谢谢前辈了,我好像明白了前辈要表达的意思了

引用 11 楼 xuzuning 的回复:
实测只有  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识一种结果
并不存在楼主描述的现象

前辈不要一直点,就是等一会再点,等线程完了,就是1,2,3了

#14


引用 10 楼 sp1234 的回复:
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。

好的,谢谢前辈了,我记下了

#15


引用 12 楼 qq_17486399 的回复:
Quote: 引用 5 楼 chenggaohua 的回复:

Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

是支持Task,但是不支持异步await


引用 8 楼 u010941149 的回复:
Quote: 引用 6 楼 chenggaohua 的回复:

Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

            Parallel.Invoke(() =>
            {
                setIv(3, 1);
            }, () =>
            {
                setIv(4, 2);
            }, () =>
            {
                setIv(5, 3);
            });
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3));
可是奇怪的是,人家这个可以中断,不知道为什么

    public class BookShop
        {
            Random rand = new Random();
            Queue<Book> queueBook = new Queue<Book>();
            int Max = 10000;
            int EachCount = 500;
            int Cur = 0;

            void LoadData()
            {
                if (Cur >= Max)
                {
                    //when Cur>=Max,return
                    Console.WriteLine("Reached max value!");
                    return;
                }
                Console.WriteLine("Loading data...");
                for (int i = Cur; i < EachCount + Cur; i++)
                {
                    Thread.Sleep(10);
                    Console.Write(i + " ");
                    //insert data into Queue<Book>
                    queueBook.Enqueue(new Book { Id = i, Name = "Name_" + i });
                }
                Console.WriteLine("");
                Cur += EachCount;
                Console.WriteLine("Data loaded successful,{0}...", queueBook.Count);
            }

            public void Run()
            {
                LoadData();
                int im = EachCount > 10 ? 10 : EachCount;
                if (im < 1)
                {
                    return;
                }
                Console.WriteLine("Tasks have started...");
                do
                {
                    Task[] tasks = new Task[im];
                    for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }
                    //// Wait for all tasks to complete.
                    Task.WaitAll(tasks);
                    //when Queue<Book> is empty,reload data...
                    LoadData();
                } while (queueBook.Count > 0);
                //when Cur>=Max,break the while loop
                Console.WriteLine("All tasks have completed.");
            }

            void DoSomeWork(int val)
            {
                while (queueBook.Count > 0)
                {
                    var m = queueBook.Dequeue();
                    if (m == null) continue;
                    Console.WriteLine("DoSomeWork start,i={0},Current thread id:{1}...", m.Id, Thread.CurrentThread.ManagedThreadId);
                    var sleep = rand.Next(10, 200);
                    // Pretend to do something.
                    Thread.Sleep(sleep);
                    Console.WriteLine("DoSomeWork has completed,sleep:{0},i={1}", sleep, m.Id);
                }
            }
        }

#16


引用 15 楼 chenggaohua 的回复:
Quote: 引用 12 楼 qq_17486399 的回复:

Quote: 引用 5 楼 chenggaohua 的回复:

Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

他这个可以终端,是因为他没有用到i
如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

是支持Task,但是不支持异步await


引用 8 楼 u010941149 的回复:
Quote: 引用 6 楼 chenggaohua 的回复:

Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

            Parallel.Invoke(() =>
            {
                setIv(3, 1);
            }, () =>
            {
                setIv(4, 2);
            }, () =>
            {
                setIv(5, 3);
            });
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3));
可是奇怪的是,人家这个可以中断,不知道为什么

    public class BookShop
        {
            Random rand = new Random();
            Queue<Book> queueBook = new Queue<Book>();
            int Max = 10000;
            int EachCount = 500;
            int Cur = 0;

            void LoadData()
            {
                if (Cur >= Max)
                {
                    //when Cur>=Max,return
                    Console.WriteLine("Reached max value!");
                    return;
                }
                Console.WriteLine("Loading data...");
                for (int i = Cur; i < EachCount + Cur; i++)
                {
                    Thread.Sleep(10);
                    Console.Write(i + " ");
                    //insert data into Queue<Book>
                    queueBook.Enqueue(new Book { Id = i, Name = "Name_" + i });
                }
                Console.WriteLine("");
                Cur += EachCount;
                Console.WriteLine("Data loaded successful,{0}...", queueBook.Count);
            }

            public void Run()
            {
                LoadData();
                int im = EachCount > 10 ? 10 : EachCount;
                if (im < 1)
                {
                    return;
                }
                Console.WriteLine("Tasks have started...");
                do
                {
                    Task[] tasks = new Task[im];
                    for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }
                    //// Wait for all tasks to complete.
                    Task.WaitAll(tasks);
                    //when Queue<Book> is empty,reload data...
                    LoadData();
                } while (queueBook.Count > 0);
                //when Cur>=Max,break the while loop
                Console.WriteLine("All tasks have completed.");
            }

            void DoSomeWork(int val)
            {
                while (queueBook.Count > 0)
                {
                    var m = queueBook.Dequeue();
                    if (m == null) continue;
                    Console.WriteLine("DoSomeWork start,i={0},Current thread id:{1}...", m.Id, Thread.CurrentThread.ManagedThreadId);
                    var sleep = rand.Next(10, 200);
                    // Pretend to do something.
                    Thread.Sleep(sleep);
                    Console.WriteLine("DoSomeWork has completed,sleep:{0},i={1}", sleep, m.Id);
                }
            }
        }

他这个可以终端,是因为他没用用到i,

 for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

#17


C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

#18


这是奇了怪了!你是写作
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }
            Task.WaitAll(tasks);

那么传递给 testTask 的都是 3,根本就没有机会去修改 i1, i2, i3,何况等待一个空循环执行完毕,是不需要花时间的
而写作
            for (int i = 0; i < 3; i++)
            {
                var a = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(a));
            }
            Task.WaitAll(tasks);

直接就是  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识 完全符合 Task.WaitAll(tasks); 是等待 tasks 全部执行完后继续的初衷
难道我的 C#4.0 与你的不同?

#19


引用 10 楼 sp1234 的回复:
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。


引用 17 楼 u010941149 的回复:
C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识


private void button1_Click(object sender, EventArgs e)
        {
            Task[] tasks = new Task[3];
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[j] = Task.Factory.StartNew(() => testTask(j));
            }
            Task.WaitAll(tasks);
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3)); 
        }

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识
谢谢各位前辈了,学习的时候不认真,现在给各位添麻烦了,一定恶补,必须补补

#20


该回复于2018-01-31 17:08:23被管理员删除

#21


看的不太懂,不过也挺有用的

#1


目前的情况是,第一下单击,出现0,0,0  再等一下1,0,0然后一次1,2,3
而我想要的是,直接卡死在这里,直到拿到1,2,3 
难道要用死循环等待吗
请各位前辈指点迷津

#2


await Task.WhenAll()

#3


你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

#4


例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

#5


引用 2 楼 starfd 的回复:
await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

#6


引用 3 楼 starfd 的回复:
你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

#7


引用 4 楼 sp1234 的回复:
例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

前辈回复给我的内容,没看明白,想前辈这么写,应该是有三个task,九个新线程

#8


引用 6 楼 chenggaohua 的回复:
Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

#9


引用 7 楼 chenggaohua 的回复:
Quote: 引用 4 楼 sp1234 的回复:

例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

前辈回复给我的内容,没看明白,想前辈这么写,应该是有三个task,九个新线程

很明显,lambda表达式捕获的是全局静态的变量,,,,,,,

#10


            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。

#11


实测只有  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识一种结果
并不存在楼主描述的现象

#12


引用 5 楼 chenggaohua 的回复:
Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

#13


引用 4 楼 sp1234 的回复:
例如
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }

这类代码,你首先要意识到,通常需要
            for (int i = 0; i < 3; i++)
            {
                            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }
            }
这种复制变量到新的语句块内局部变量的操作。自己跟踪2个异步子线程的执行过程。

谢谢前辈了,我好像明白了前辈要表达的意思了

引用 11 楼 xuzuning 的回复:
实测只有  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识一种结果
并不存在楼主描述的现象

前辈不要一直点,就是等一会再点,等线程完了,就是1,2,3了

#14


引用 10 楼 sp1234 的回复:
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。

好的,谢谢前辈了,我记下了

#15


引用 12 楼 qq_17486399 的回复:
Quote: 引用 5 楼 chenggaohua 的回复:

Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

是支持Task,但是不支持异步await


引用 8 楼 u010941149 的回复:
Quote: 引用 6 楼 chenggaohua 的回复:

Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

            Parallel.Invoke(() =>
            {
                setIv(3, 1);
            }, () =>
            {
                setIv(4, 2);
            }, () =>
            {
                setIv(5, 3);
            });
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3));
可是奇怪的是,人家这个可以中断,不知道为什么

    public class BookShop
        {
            Random rand = new Random();
            Queue<Book> queueBook = new Queue<Book>();
            int Max = 10000;
            int EachCount = 500;
            int Cur = 0;

            void LoadData()
            {
                if (Cur >= Max)
                {
                    //when Cur>=Max,return
                    Console.WriteLine("Reached max value!");
                    return;
                }
                Console.WriteLine("Loading data...");
                for (int i = Cur; i < EachCount + Cur; i++)
                {
                    Thread.Sleep(10);
                    Console.Write(i + " ");
                    //insert data into Queue<Book>
                    queueBook.Enqueue(new Book { Id = i, Name = "Name_" + i });
                }
                Console.WriteLine("");
                Cur += EachCount;
                Console.WriteLine("Data loaded successful,{0}...", queueBook.Count);
            }

            public void Run()
            {
                LoadData();
                int im = EachCount > 10 ? 10 : EachCount;
                if (im < 1)
                {
                    return;
                }
                Console.WriteLine("Tasks have started...");
                do
                {
                    Task[] tasks = new Task[im];
                    for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }
                    //// Wait for all tasks to complete.
                    Task.WaitAll(tasks);
                    //when Queue<Book> is empty,reload data...
                    LoadData();
                } while (queueBook.Count > 0);
                //when Cur>=Max,break the while loop
                Console.WriteLine("All tasks have completed.");
            }

            void DoSomeWork(int val)
            {
                while (queueBook.Count > 0)
                {
                    var m = queueBook.Dequeue();
                    if (m == null) continue;
                    Console.WriteLine("DoSomeWork start,i={0},Current thread id:{1}...", m.Id, Thread.CurrentThread.ManagedThreadId);
                    var sleep = rand.Next(10, 200);
                    // Pretend to do something.
                    Thread.Sleep(sleep);
                    Console.WriteLine("DoSomeWork has completed,sleep:{0},i={1}", sleep, m.Id);
                }
            }
        }

#16


引用 15 楼 chenggaohua 的回复:
Quote: 引用 12 楼 qq_17486399 的回复:

Quote: 引用 5 楼 chenggaohua 的回复:

Quote: 引用 2 楼 starfd 的回复:

await Task.WhenAll()

前辈我目前用的是net4.0,不换4.5的话,怎么弄呢

他这个可以终端,是因为他没有用到i
如果我没记错.NET4.0已经支持了Task了,为什么要换4.5呢

是支持Task,但是不支持异步await


引用 8 楼 u010941149 的回复:
Quote: 引用 6 楼 chenggaohua 的回复:

Quote: 引用 3 楼 starfd 的回复:

你这个代码有必要这样做吗?你直接用Parallel.For不是更好?

谢谢前辈了,这个方法实现了我想要的功能,跪拜跪拜

Parallel.For你怎么写的?贴出来检查检查

            Parallel.Invoke(() =>
            {
                setIv(3, 1);
            }, () =>
            {
                setIv(4, 2);
            }, () =>
            {
                setIv(5, 3);
            });
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3));
可是奇怪的是,人家这个可以中断,不知道为什么

    public class BookShop
        {
            Random rand = new Random();
            Queue<Book> queueBook = new Queue<Book>();
            int Max = 10000;
            int EachCount = 500;
            int Cur = 0;

            void LoadData()
            {
                if (Cur >= Max)
                {
                    //when Cur>=Max,return
                    Console.WriteLine("Reached max value!");
                    return;
                }
                Console.WriteLine("Loading data...");
                for (int i = Cur; i < EachCount + Cur; i++)
                {
                    Thread.Sleep(10);
                    Console.Write(i + " ");
                    //insert data into Queue<Book>
                    queueBook.Enqueue(new Book { Id = i, Name = "Name_" + i });
                }
                Console.WriteLine("");
                Cur += EachCount;
                Console.WriteLine("Data loaded successful,{0}...", queueBook.Count);
            }

            public void Run()
            {
                LoadData();
                int im = EachCount > 10 ? 10 : EachCount;
                if (im < 1)
                {
                    return;
                }
                Console.WriteLine("Tasks have started...");
                do
                {
                    Task[] tasks = new Task[im];
                    for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }
                    //// Wait for all tasks to complete.
                    Task.WaitAll(tasks);
                    //when Queue<Book> is empty,reload data...
                    LoadData();
                } while (queueBook.Count > 0);
                //when Cur>=Max,break the while loop
                Console.WriteLine("All tasks have completed.");
            }

            void DoSomeWork(int val)
            {
                while (queueBook.Count > 0)
                {
                    var m = queueBook.Dequeue();
                    if (m == null) continue;
                    Console.WriteLine("DoSomeWork start,i={0},Current thread id:{1}...", m.Id, Thread.CurrentThread.ManagedThreadId);
                    var sleep = rand.Next(10, 200);
                    // Pretend to do something.
                    Thread.Sleep(sleep);
                    Console.WriteLine("DoSomeWork has completed,sleep:{0},i={1}", sleep, m.Id);
                }
            }
        }

他这个可以终端,是因为他没用用到i,

 for (int i = 0; i < im; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() => DoSomeWork(1000 * 1));
                    }

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

#17


C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

#18


这是奇了怪了!你是写作
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }
            Task.WaitAll(tasks);

那么传递给 testTask 的都是 3,根本就没有机会去修改 i1, i2, i3,何况等待一个空循环执行完毕,是不需要花时间的
而写作
            for (int i = 0; i < 3; i++)
            {
                var a = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(a));
            }
            Task.WaitAll(tasks);

直接就是  C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识 完全符合 Task.WaitAll(tasks); 是等待 tasks 全部执行完后继续的初衷
难道我的 C#4.0 与你的不同?

#19


引用 10 楼 sp1234 的回复:
            for (int i = 0; i < 3; i++)
            {
                tasks[i] = Task.Factory.StartNew(() => testTask(i));
            }


通常需要写
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[i] = Task.Factory.StartNew(() => testTask(j));
            }


上面因为突然有急事,被耽误了。


引用 17 楼 u010941149 的回复:
C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识


private void button1_Click(object sender, EventArgs e)
        {
            Task[] tasks = new Task[3];
            for (int i = 0; i < 3; i++)
            {
                var j = i;
                tasks[j] = Task.Factory.StartNew(() => testTask(j));
            }
            Task.WaitAll(tasks);
            MessageBox.Show(string.Format("见到你很高兴.{0},{1},{2}", i1, i2, i3)); 
        }

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识

C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识C# Task.WaitAll无法阻止主线程,等待全部完成,难道下一句要死循环判断结束标识
谢谢各位前辈了,学习的时候不认真,现在给各位添麻烦了,一定恶补,必须补补

#20


该回复于2018-01-31 17:08:23被管理员删除

#21


看的不太懂,不过也挺有用的