using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
TaskFactory taskFactory = new TaskFactory();
Task[] t = new Task[3];
for (int i = 0; i < 3; i++)
{
t[i] = taskFactory.StartNew(() => get(i.ToString()));
Thread.Sleep(1000);
}
Task.WaitAll(t);
Console.ReadKey();
}
public static void get(string u)
{
Thread.Sleep(5000);
Console.WriteLine(u);
}
}
}
}这里的红色代码部分去掉的话输出是 3 3 3
如果加上红色部分,可以正常输出是 0 1 2本人水平有限,实在不能理解这是什么原因,请各位懂的朋友指导一下。
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
TaskFactory taskFactory = new TaskFactory();
Task[] t = new Task[3];
for (int i = 0; i < 3; i++)
{
t[i] = taskFactory.StartNew(() => get(i.ToString()));
Thread.Sleep(1000);
}
Task.WaitAll(t);
Console.ReadKey();
}
public static void get(string u)
{
Thread.Sleep(5000);
Console.WriteLine(u);
}
}
}
}这里的红色代码部分去掉的话输出是 3 3 3
如果加上红色部分,可以正常输出是 0 1 2本人水平有限,实在不能理解这是什么原因,请各位懂的朋友指导一下。
2.加一个局部变量。 for (int i = 0; i < 3; i++)
{
var it = i;
t[i] = taskFactory.StartNew(() => get(it.ToString()));
// Thread.Sleep(1000);
}其实可以从 堆栈的内存分配来看看。
1)直接使用i,在堆栈中只有一个i=多少,只有一份,每个线程取值时,就是取值时的i的值,因为给get方法的i都是同一i。
2)加了it,堆栈中就分配了 3个 it,不同的内存地址,每个线程都找到了当时给的it。
i.ToString() 将不会及时执行 而是在linq直接运行的时候才会执行
(() => get(i.ToString()) 只是创建一个表达式 在执行的时候的时候可能已经完成了整个循环与线程的互斥没有关系的 因为应该没有共享变量之类的
你应该做的是吧值的构成和linq分开 就是先执行ToString() 在构建linq语句
-------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
TaskFactory taskFactory = new TaskFactory();
Task[] t = new Task[3];
for (int i = 0; i < 3; i++)
{
string str = i.ToString();
t[i] = taskFactory.StartNew(() => get(str));
// Thread.Sleep(1000);
}
Task.WaitAll(t);
Console.ReadKey();
}
public static void get(string u)
{
Thread.Sleep(5000);
Console.WriteLine(u);
}
}
}-------------------------------------------------------
可以满足你的要求 实际原因是linq语句的实际执行时间可能会比语句构造迟一点
试试支持.net2.0的fastCSharp
fastCSharp.threading.task task = new fastCSharp.threading.task(3);
for (int i = 0; i < 3; i++) task.Add(get, i.ToString());
task.Dispose(true);
Console.ReadKey();