C# 线程 创建和使用

原文地址: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");
        }
    }












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值