zoukankan      html  css  js  c++  java
  • C# 中传递多个参数给多线程

    1.方式一:使用ParameterizedThreadStart委托

    如果使用了ParameterizedThreadStart委托,线程的入口必须有一个object类型的参数,且返回类型为void.

     View Code
    using System;
     using System.Threading;
      
     namespace ThreadWithParameters
     {
         class Program
         {
             static void Main(string[] args)
             {
                 string hello = "hello world";
      
                 //这里也可简写成Thread thread = new Thread(ThreadMainWithParameters);
                 //但是为了让大家知道这里用的是ParameterizedThreadStart委托,就没有简写了
                 Thread thread = new Thread(new ParameterizedThreadStart(ThreadMainWithParameters));
                 thread.Start(hello);
      
                 Console.Read();
             }
      
             static void ThreadMainWithParameters(object obj)
             {
                 string str = obj as string;
                 if(!string.IsNullOrEmpty(str))
                     Console.WriteLine("Running in a thread,received: {0}", str);
             }
         }
     }

    以上代码只能传递一个参数,如果有时我们向线程传递给多的参数,那种方式使用将有局限性(如果用类作为对象传递参数,那么需要要另外建立一个类,也稍有点麻烦) 
    如果用这种方法我们密切要注意的就是ThreadMainWithParameters方法里的参数必须是object类型的,我们需要进行类型转换。此方法不作推荐。

     2.方式二: 创建自定义类

    定义一个类,在其中定义需要的字段,将线程的主方法定义为类的一个实例方法,请看实际的例子。

     View Code
    using System;
     using System.Threading;
      
     namespace ThreadWithParameters
     {
         public class MyThread
         {
             private string data;
      
             public MyThread(string data)
             {
                 this.data = data;
             }
      
             public void ThreadMain()
             {
                 Console.WriteLine("Running in a thread,data: {0}", data);
             }
         }
      
         class Program
         {
             static void Main(string[] args)
             {
                 MyThread myThread = new MyThread("hello world");
      
                 Thread thread = new Thread(myThread.ThreadMain);
                 thread.Start();
      
                 Console.Read();
             }
         }
     }

    这种方法也稍有繁琐,也不是我重点想要探讨的,如果需要,自己也可以使用。 
    3. 方式三:采用lambda表达式

    对于lambda表达式不熟悉的可以查看微软MSDN上的说明文档。此处假设你熟悉。因为在大多数使用委托的时候我们一般也可以用lambda表达式的。

     View Code
    using System;
     using System.Threading;
      
     namespace ThreadWithParameters
     {
         class Program
         {
             static void Main(string[] args)
             {
                 string hello = "hello world";
      
                 //如果写成Thread thread = new Thread(ThreadMainWithParameters(hello));这种形式,编译时就会报错
                 Thread thread = new Thread(() => ThreadMainWithParameters(hello));
                 thread.Start();
      
                 Console.Read();
             }
      
             static void ThreadMainWithParameters(string str)
             {
                  Console.WriteLine("Running in a thread,received: {0}", str);
             }
         }
     }

    此方法三可以作为推荐方法,代码简便,方便我们使用。上面方式三说到lambda表达式,既然lambda表达式可以使用,那么我们也可以使用delegate委托。下面主要探讨的是使用这种方法。 
    4. 方式三:使用delegate委托

    Multhd = new Thread[ThreadCount];
                thread_Separate_baseCount = C_num / ThreadCount;//每个线程的终端数
                listViewEx2.Items.Clear();
                for (int j = 0; j < ThreadCount; j++)
                {
                    if (j == ThreadCount - 1)//最后一个线程
                    {
                        Multhd[j] = new Thread(delegate() { Run2( j * thread_Separate_baseCount,  C_num - 1); });
                    }
                    else//其它线程
                    {
                        Multhd[j] = new Thread(delegate() { Run2( j * thread_Separate_baseCount, (j + 1) * thread_Separate_baseCount - 1); });
                    }
    }

    上面代码Run(arg1,arg2.....,argn)是我们自定义的方法,在这个方法中我们可以设置任意多个参数,看也算是简单的吧。

    以上代码完全可以运行,也不会出现bug什么之类的,但是实际运行情况却令我惊讶不已,用for循环创建一个线程时,关闭重开线程不会有任何问题。因为只是一个线程,可能没有什么事。但是至二个或者二个以上时,关闭再重开线程(我需要不断关闭打开终端),程序不会报错,调试器也没有什么问题,电脑有时会毫无预兆的关机,在我们做事时毫无预兆的关机这可是一个致命的问题啊,没有谁愿意这样的。以为是偶然,重复了多次结果都一样,偶然也必然存在这种必然。

    为什么一个线程时没事,多个线程时运行时是不是上面的线程都指向了同一个delegate委托的地址,才导致这样会毫无预兆的关机?这些等待我们去验证,在此热烈欢迎有经验的朋友和我一块探讨。

  • 相关阅读:
    JQuery 图片轮播
    js版的虚线框
    折叠菜单,选择下拉(手风琴)
    logstash的index值可以为中文
    假如正则从来没来过,我们该如何去匹配一个字符串?
    深度解析javascript中的浅复制和深复制
    笔试题
    前端笔试题总结---持续更新
    清除浮动
    一步一步的理解闭包
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/5416883.html
Copyright © 2011-2022 走看看