带参数的多线程的方式

带参数的多线程的方式

 
 
#region 执行带一个参数的多线程
            Thread mythread = new Thread(new ParameterizedThreadStart(Calculate));
            mythread.IsBackground = true;       
            mythread.Start(500);
            #endregion

        private void Calculate(object Max)              //带一个参数的委托函数  
        {
            int max = (int)Max;
            Stopwatch stopwatch = Stopwatch.StartNew();
            for (int i = 0; i < max; i++)
            {
                Thread.Sleep(5);
            }
            stopwatch.Stop();
            long lSearchTime = stopwatch.ElapsedMilliseconds;
            MessageBox.Show(lSearchTime.ToString() + "毫秒");
        }



方式一: 定义一个类,将要传的参数设置为类的属性,然后将参数值赋值给类的属性,将类作为一个参数进行传达,以下代码通过两个参数示例,多个参数一样,代码如下

复制代码
复制代码
    class MyClass
    {
        public int Max { get; set; }
        public int Min { get; set; }
    }
            #region 第一种方式:执行带多个参数的多线程
            MyClass model = new MyClass();
            model.Max = 500;
            model.Min = 0;
            Thread mythread1 = new Thread(new ParameterizedThreadStart(CalculateTwo));
            mythread1.IsBackground = true;       
            mythread1.Start(model);
            #endregion
        private void CalculateTwo(object Myclass)              //带多个参数的委托函数  
        {
            MyClass model = (MyClass)Myclass;
            Stopwatch stopwatch = Stopwatch.StartNew();
            for (int i = model.Min; i < model.Max; i++)
            {
                Thread.Sleep(5);
            }
            stopwatch.Stop();
            long lSearchTime = stopwatch.ElapsedMilliseconds;
            MessageBox.Show(lSearchTime.ToString() + "毫秒");
        }
复制代码
复制代码

方式二:lambda表达式的方式,简单方便,代码如下:



#region 第二种方式:执行带多个参数的多线程
            Thread mythread2 = new Thread(() => CalculateThree(500, 0));
            mythread2.IsBackground = true;        //設置為後臺線程,程式關閉后進程也關閉,如果不設置true,則程式關閉,此線程還在內存,不會關閉
            mythread2.Start(); 
            #endregion
        private void CalculateThree(int Max,int Min)              //带多个参数的委托函数  
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            for (int i = Min; i < Max; i++)
            {
                Thread.Sleep(5);
            }
            stopwatch.Stop();
            long lSearchTime = stopwatch.ElapsedMilliseconds;
            MessageBox.Show(lSearchTime.ToString() + "毫秒");
        }



在 .NET Framework 2.0 版中,要实现线程调用带参数的方法有两种办法。

第一种:使用ParameterizedThreadStart。

 调用 System.Threading.Thread.Start(System.Object) 重载方法时将包含数据的对象传递给线程。

使用 ParameterizedThreadStart 委托不是传递数据的类型安全的方法,因为 System.Threading.Thread.Start(System.Object) 方法重载接受任何对象。

 这种方法不推荐使用,故在此不做详细介绍,具体用法参见:http://msdn2.microsoft.com/zh-cn/library/system.threading.parameterizedthreadstart(VS.80).aspx


复制代码
ParameterizedThreadStart ParStart = new ParameterizedThreadStart(ThreadMethod);
 Thread myThread = new Thread(ParStart);
object o = "hello";
 myThread.Start(o);

//ThreadMethod如下:
public void ThreadMethod(object ParObject)
 {
     //程序代码
}
复制代码


第二种:将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递参数。

 具体代码如下(本示例来自MSDN)


复制代码
using System;
using System.Threading;

//ThreadWithState 类里包含了将要执行的任务以及执行任务的方法
public class ThreadWithState {
     //要用到的属性,也就是我们要传递的参数
    private string boilerplate;
     private int value;

     //包含参数的构造函数
    public ThreadWithState(string text, int number)
     {
         boilerplate = text;
         value = number;
     }

     //要丢给线程执行的方法,本处无返回类型就是为了能让ThreadStart来调用
    public void ThreadProc()
     {
         //这里就是要执行的任务,本处只显示一下传入的参数
         Console.WriteLine(boilerplate, value);
     }
 }

//用来调用上面方法的类,是本例执行的入口
public class Example {
     public static void Main()
     {
         //实例化ThreadWithState类,为线程提供参数
        ThreadWithState tws = new ThreadWithState(
             "This report displays the number {0}.", 42);

         // 创建执行任务的线程,并执行
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
         t.Start();
         Console.WriteLine("Main thread does some work, then waits.");
         t.Join();
         Console.WriteLine(
             "Independent task has completed; main thread ends."); 
     }
 }

复制代码

 

============================================================================

方法一:
 在VS2003中,也不能直接访问,参看 
一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能 简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。 

现在用一个用线程控制的进程条来说明,大致的步骤如下: 

1.创建Invoke函数,大致如下: 
 /// <summary> 
 /// Delegate function be invoked by main thread 
 /// </summary> 
 private     void     InvokeFun() 
 { 
     if(prgBar.Value< 100) 
     prgBar.Value = prgBar.Value + 1; 
 } 

2.子线程入口函数: 
 /// <summary> 
 /// Thread function interface 
 /// </summary> 
 private void ThreadFun() 
 { 
     // Create invoke method by specific function
     MethodInvoker mi = new MethodInvoker(this.InvokeFun); 

    for(int i=0; i<100; i++) 
     { 
       this.BeginInvoke(mi);   
       Thread.Sleep(100); 
     } 
 }

3.创建子线程: 
Thread thdProcess = new Thread(new ThreadStart(ThreadFun)); 
 thdProcess.Start(); 

备注: 
     using System.Threading; 
     private System.Windows.Forms.ProgressBar prgBar; 

方法二:
 加入该句:Control.CheckForIllegalCrossThreadCalls = False    取消线线程安全保护模式!

方法三:带参数
使用类、类的方法或类的属性都可以向线程传递参数:
public class UrlDownloader
 {
     string url;
  
     public UrlDownloader (string url)
     {
       this.url = url;
     }
  
     public void Download()
     {
       WebClient wc = new WebClient();
       Console.WriteLine("Downloading " + url);                       
       byte[] buffer = wc.DownloadData (url);
       string download = Encoding.ASCII.GetString(buffer);
       Console.WriteLine(download);
       Console.WriteLine("Download successful.");
    
       //这里你可以将download进行保存等处理......
     }
 }

[... 在另一个类中使用它们...]
              
UrlDownloader downloader = new UrlDownloader (yourUrl);
 new Thread (new ThreadStart (downloader.Download)).Start();

注意参数是如何传递的。

方法四:带参数
ThreadStart starter = delegate { Download(yourUrl); };
 new Thread(starter).Start();

 //使用线程池
WaitCallback callback = delegate (object state) { Download ((string)state); };
 ThreadPool.QueueUserWorkItem (callback, yourUrl);

方法五:带参数
Thread t = new Thread (new ParameterizedThreadStart(DownloadUrl));
 t.Start (myUrl);
static void DownloadUrl(object url)
 {
   // ....
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值