.net中向线程过程传递参数的最优方法

简介:     线程执行的关键是线程过程函数。一般我们会使用ThreadStart委托来调用线程过程。很多时候,线程过程也需要传入一些参数,这该如何处理?这就是本文写作的原因了。 一、ThreadStart委托的优劣测试     ThreadStart委托对应的线程过程...

    线程执行的关键是线程过程函数。一般我们会使用ThreadStart委托来调用线程过程。很多时候,线程过程也需要传入一些参数,这该如何处理?这就是本文写作的原因了。

一、ThreadStart委托的优劣测试

    ThreadStart委托对应的线程过程是不能包括参数的,如:


  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("Run before thread start ....");
  6.         Thread testThread = new Thread(new ThreadStart(ThreadFunction));
  7.         testThread.Start();
  8.         Console.WriteLine("---------------------------------------.");
  9.         Console.ReadLine();
  10.     }

  11.     public static void ThreadFunction()
  12.     {
  13.         Console.WriteLine("Thread is running ...");
  14.     }
  15. }


image
图1

    图1是上面代码的执行效果。可以看到,虽然testThread.start()执行后才输出横线,但实际却是输出横线比线程方法先执行了

    这说明在多线程中,代码的先写并不能被先执行。而当有些情况必须先执行线程方法再执行后面的操作,该怎么办?

    这就要复习Thread的Join函数了。Join方法的作用是阻塞调用线程,直到某线程终止时为止。修改下Main中的代码:


  1. static void Main(string[] args)
  2. {
  3.     Console.WriteLine("Run before thread start ....");
  4.     Thread testThread = new Thread(new ThreadStart(ThreadFunction));
  5.     testThread.Start();
  6.     testThread.Join();
  7.     Console.WriteLine("---------------------------------------.");
  8.     Console.ReadLine();
  9. }


image 图2

 

    上面的情况是最理想、最和谐的情况而当需要给ThreadFunction()传递一个参数的时候,ThreadStart()是无能为力的

    这里.net又提供了一个ParameterizedThreadStart委托。

 

二、ParameterizedThreadStart委托的优劣测试

    该委托的原型为:

    ParameterizedThreadStart(Object obj),可以看到它的参数的一个任意类型。

    案例如下:


  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("Run before thread start ....");
  6.         Thread testThread = new Thread(new ParameterizedThreadStart(ThreadFunction));
  7.         testThread.Start("Send parameter to thread function......");
  8.         Console.WriteLine("---------------------------------------.");
  9.         Console.ReadLine();
  10.     }

  11.     public static void ThreadFunction(object obj)
  12.     {
  13.         Console.WriteLine("{0}",(string)obj);
  14.     }
  15. }


image
图3



    从图3的运行效果,上面代码中通过在start()中传入参数,而实现了给线程过程传递参数的目的。

    而这里有一个问题需要注意:由于ParameterizedThreadStart委托的参数是Object类型的,意思是可以将任意类型的数据传递到线程过程,这种方法并不是类型安全的。这又该如何处理?这就需要引入一个辅助器类来解决这个问题。

 

三、通过辅助器类来实现在创建线程时传递数据

    通过在辅助器类中封装线程过程和一些相关数据,创建辅助器类实例时填写好数据;将辅助器类的实例线程过程赋给ThreadStart,即可以实现目的。


  1. // The ThreadWithState class contains the information needed for
  2. // a task, and the method that executes the task.
  3. //
  4. public class ThreadWithState
  5. {
  6.     // State information used in the task.
  7.     private string boilerplate;
  8.     private int value;
  9.     // The constructor obtains the state information.
  10.     public ThreadWithState(string text, int number)
  11.     {
  12.         boilerplate = text;
  13.         value = number;
  14.     }
  15.     // The thread procedure performs the task, such as formatting
  16.     // and printing a document.
  17.     public void ThreadProc()
  18.     {
  19.         Console.WriteLine(boilerplate, value);
  20.     }
  21. }

  22. public class Example
  23. {
  24.     public static void Main()
  25.     {
  26.         // Supply the state information required by the task.
  27.         ThreadWithState tws = new ThreadWithState("This report displays the number {0}.", 42);
  28.         // Create a thread to execute the task, and then
  29.         // start the thread.
  30.         Thread t = new Thread(new ThreadStart(tws.ThreadProc));
  31.         t.Start();
  32.         Console.WriteLine("Main thread does some work, then waits.");
  33.         t.Join();
  34.         Console.WriteLine("Independent task has completed; main thread ends.");
  35.         Console.ReadLine();
  36.     }
  37. }


image 图4

 

参考文献

MSDN--启动时创建线程并传递数据

相关文章
|
18天前
|
存储 Oracle Java
|
3月前
|
Java
创建线程的方法
Java中实现多线程有四种方式:1. 继承Thread类,简单但占用继承机会,耦合度高;2. 实现Runnable接口,推荐方式,任务与线程解耦,支持Lambda;3. 实现Callable接口配合FutureTask,可获取返回值和异常;4. 使用线程池(ExecutorService),企业推荐,管理线程生命周期,提升性能,支持多种线程池类型。
72 1
|
4月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
250 5
|
12月前
|
监控 Java
捕获线程执行异常的多种方法
【10月更文挑战第15天】捕获线程执行异常的方法多种多样,每种方法都有其特点和适用场景。在实际开发中,需要根据具体情况选择合适的方法或结合多种方法来实现全面有效的线程异常捕获。这有助于提高程序的健壮性和稳定性,减少因线程异常带来的潜在风险。
233 57
|
11月前
|
开发框架 Java .NET
.net core 非阻塞的异步编程 及 线程调度过程
【11月更文挑战第12天】本文介绍了.NET Core中的非阻塞异步编程,包括其基本概念、实现方式及应用示例。通过`async`和`await`关键字,程序可在等待I/O操作时保持线程不被阻塞,提高性能。文章还详细说明了异步方法的基础示例、线程调度过程、延续任务机制、同步上下文的作用以及如何使用`Task.WhenAll`和`Task.WhenAny`处理多个异步任务的并发执行。
196 1
|
10月前
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
10月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
12月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
196 3
|
12月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
109 2
|
12月前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
153 1