外部参数传入线程的方法

在C#开发中,线程是很重要的一个方面。一般在线程中会处理一些常规的周期性的事务,我们会通过Thread.Sleep(int)或者Thread.Join(int)这两种方式来使线程休眠(阻塞)。这两者的区别在于Sleep是线程类的静态方法,当执行Sleep方法时,所有的线程都会被休眠;而Join方法则是实例方法,只针对本线程起作用而已。

不论是Sleep或者是Join方法我们一般都会放在线程初始化中ThreadStart委托所设置的情景中进行。如下例所示:


class ThreadProcess
    {
        Thread t1;;

        public ThreadProcess()
        {
            t1 = new Thread(new ThreadStart(this.threading));
        }

        public void start()
        {
            t1.Start();
        }

        private void threading()
        {
            while (true)
            {
                //do something
                t1.Join(20000);
            }
        }
在这个例子中每隔20秒左右线程就会苏醒一次执行某个动作。而整个线程的启动完全有threading这个方法所决定的。有ThreadStart这个委托的定义我们可以知道这是一个不带参数的委托。如果我们需要在线程的执行过程中如果我们需要有参数传入,则在初始化线程的时候使用new ParameterizedThreadStart这个初始化参数。根据这个参数的形式我们可以知道,在初始化时可以传入一个object类型的参数,而且这个object参数也只能在start的时候起到作用。当指定到线程体时,这个参数依然不能发挥作用,而且参数的类型和个数都受到了极大的限制。那么有没有什么办法能够在while(true)的循环中使得外部参数能够在线程体的执行过程中参与呢?

办法就是使用Observer的观察者模式并且结合.NET特有的委托-事件处理模式进行处理。代码如下所示:

 


    delegate void doThread();
    class ThreadProcess
    {
        WrITeFile wf;
        Thread t1;
        event doThread dt;

        public ThreadProcess()
        {
            wf = new WriteFile();
            t1 = new Thread(new ThreadStart(this.threading));
            new ParameterizedThreadStart
            dt += wf.WirteLog;
        }

        public void start()
        {
            t1.Start();
        }

        private void threading()
        {
            while (true)
            {
                dt();
                t1.Join(20000);
            }
        }
    }

 

    class WriteFile
    {
        StreamWriter sw=null;
        int count = 1;
        string content;

        public WriteFile()
        {
            DirectoryInfo directory = new DirectoryInfo(@"../../log");
            int i = 0;

if  (!directory.Exists)
            {
                directory.Create();
            }
            FileInfo[] fis = directory.GetFiles(DateTime.Now.ToString( "yyyyMMdd-" ) +  "*.log" , SearchOption.TopDirectoryOnly);
             foreach  (FileInfo fi  in  fis)
            {
                 if  (fi.Length > 1024)
                {
                    i++;
                     continue ;
                }
                 else
                {
                    sw = fi.AppendText();
                     break ;
                }
            }
             if  (sw ==  null )
            {
                sw = File.AppendText(directory.ToString() + @ "/"  + DateTime.Now.ToString( "yyyyMMdd-" ) + i.ToString() + @ ".log" );
            }
        }

         public   void  WirteLog()
        {
             if  (count == 1)
            {
                count++;
                content = DateTime.Now.ToString() +  ":第一次启动" ;
            }
             else
            {
                content = DateTime.Now.ToString() +  ":服务启动" ;
            }
            sw.WriteLine(content);
            sw.Flush();
        }
    }
在上面的代码中,我们首先声明了一个委托doThread(),然后在类ThreadProcess声明了该委托类型的一个事件dt。同时为该事件绑定了处理事件的委托方法也就是WriteFile类中的WirteLog方法。这样我们就知道当触发了事件dt时,WriteLog方法会被通知到并且开始执行。

接着我们看到了在线程的委托方法中在线程执行中我们触发了dt事件。这就意味着WriteFile类中的WirteLog方法将被召唤执行。由于WriteLog是线程外的方法,所以他使用的参数自然也就是WriteFile自己的参数,这样线程就和处理逻辑脱钩了,而被委托的方法使用的又是外部方法和参数,自然也就达到了我们所谓的外部参数传入线程的目的。

在这个示例中,线程仅仅起到了一个定时的消息触发的角色而已,真正的线程处理国际完全以后事件触发以后绑定的委托来进行操作。这样外部参数自然流入到线程内部去了。
详细出处参考:http://www.itqun.net/content-detail/121019_2.html

详细出处参考:http://www.itqun.net/content-detail/121019.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值