原文地址:http://www.cnblogs.com/miniwiki/archive/2010/06/18/1760540.html
创建线程
线程用Thread 类来创建,通过ThreadStart委托来指明方法。
public delegate void ThreadStart();
简单的例子:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(Go));
t.Start();
Go();
}
static void Go()
{
Console.WriteLine("Hello");
}
}
一般我们不需要特别使用ThreadStart,一个线程可以通过更简单的方法创建。
static void Main(string[] args)
{
Thread t = new Thread(Go);
t.Start();
Go();
}
这种情况下编译器会自动推断使用ThreadStart.
另一种办法,使用匿名方法:
static void Main(string[] args)
{
Thread t = new Thread(delegate() { Console.WriteLine("Hello"); });
t.Start();
Go();
}
节省了写方法的时间,有些时候很方便。
将参数传入线程中
当我们需要在线程中调用一个需要参数的方法时,ThreadStart就没有用了,我们需要用到另一个委托ParameterizedThreadStart,他可以接受一个单独的object类型的参数。
public delegate void ParameterizedThreadStart(object obj);
改变一下之前的例子,传入一个参数让他在输出时区分大小写:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(Go);
t.Start(true);
Go(false);
}
static void Go(object upperCase)
{
bool upper = (bool)upperCase;
Console.WriteLine(upper?"HELLO":"hello");
}
}
在这个例子中编译器识别使用了ParameterizedThreadStart委托,完整的写法:
Thread t = new Thread(new ParameterizedThreadStart(Go));
t.Start(true);
在使用ParameterizedThreadStart时,我们必须把需要传递的类型装箱(如:此处将bool装箱为object),并且这个委托只能接受一个参数。
一个替代方案使用匿名方法来调用一个方法,这样可以不需要装箱操作,也可以传递任意多个参数。
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(delegate() { WriteText("Hello"); });
t.Start();
}
static void WriteText(string text)
{
Console.WriteLine(text);
}
}
原文中,作者说到了外部变量被修改后,透过外部变量进行了无意的互动。如下:
class Program
{
static void Main(string[] args)
{
string text = "Before";
Thread t = new Thread(delegate() { WriteText(text); });
text = "After";
t.Start();
}
static void WriteText(string text)
{
Console.WriteLine(text);
}
}
以上的例子最终输出为After。这里我表示不解,这个情况是否可理解为在方法运行前,text的值已经修改造成的。
之后我尝试将例子进行修改:
static void Main(string[] args)
{
string text = "Before";
Thread t = new Thread(delegate() { WriteText(text); });
t.Start();
text = "After";
}
结果还是一样,但我又觉得这可能是由于线程t在执行WriteText时,text的值在主线程中已经被修改造成的,之后我尝试添加lock和使用t.Join()。结果都变为Before。
暂时,我认为作者所说的无意的互动有些问题,之后的使用对象实例的方法,也没有从根本上说明问题。
作者的例子:
class Program
{
bool upper;
static void Main(string[] args)
{
Program p1 = new Program();
p1.upper = true;
Thread t = new Thread(p1.Go);
t.Start();
Program p2 = new Program();
p2.Go();
}
void Go()
{
Console.WriteLine(upper ? "Hello" : "hello");
}
}