SoFunction
Updated on 2025-03-06

Summary of methods for passing parameters to threads in C#

This article summarizes and organizes the methods of passing parameters to threads for your reference. It is very practical. The specific content is as follows:

First of all, we need to know what thread is, when to use it, how to use it, and how to better utilize it to complete the work.

A thread is the smallest unit of a program executable fragment and is the basic unit that constitutes a runtime program. A process consists of at least one thread. Generally, threads are used when processing waiting events in parallel, such as waiting for network responses, waiting for I/O communication, background transaction processing, etc. Using threads is actually very simple. Under the .net framework, you first need to define a function to complete some work, and then instantiate a thread object Thread thrd = new Thread(new ThreadStart(thread function)); where ThreadStart is a function delegate without parameters. Finally, use() to start the thread. Of course, this is just a very simple example. In practice, there will be many problems to be solved when using threads, such as passing parameters to the thread, waiting for the thread to return, how to synchronize the thread for the same resource access, how to prevent deadlocks and race conditions, how to effectively utilize the thread pool, how to provide thread efficiency and other problems. This article will only discuss passing parameters to threads here.

In the above example, we see that the parameter instantiated by the thread is a function delegate without any parameters, which proves that it is impossible for us to pass parameters into the thread through such a delegate. So what should we do?

As far as I know, there are three methods that can be implemented: 1. Use thread implementation classes to define call parameters as attributes to operate thread parameters; 2. Use ParameterizedThreadStart delegate to pass input parameters; 3. Use thread pool to implement parameter incoming.

The following are described separately:

1. Create a thread implementation class, This method has the biggest advantage is that it can return multiple return values ​​through threads
Suppose there is a thread in a printing function that passes the printed rows, columns and character data through the main function and returns the total number of printed characters.

The specific code is as follows:

class ThreadOutput
{
int _rowCount = 0;
int _colCount = 0;
char _char = '*';
int _ret = 0;

/**//// <summary>
 /// Input parameters
  /// </summary>
 public int RowCount
 {
  set { _rowCount = value; }
 }

 public int ColCount
 {
  set { _colCount = value; }
 }

 public char Character
 {
  set { _char = value; }
 }

 /**//// &lt;summary&gt;
/// Output parameters /// &lt;/summary&gt;
public int RetVal
{
 get { return _ret; }
}

public void Output()
{
 for (int row = 0; row &lt; _rowCount; row++)
 {
 for (int col = 0; col &lt; _colCount; col++)
 {
  ("{0} ", _char);
  _ret++;
 }
 ("\n");
 }
}

ThreadOutput to1 = new ThreadOutput();
 = 10;
 = 20;

Thread thrd = new Thread(new ThreadStart());
// Set as a background thread, mainly to not affect the end of the main thread = true;
();

The last thing to note isSince thread implementation classes pass numeric values ​​through attributes, thread synchronization should be performed in the attribute accessor, otherwise the obtained value may be incorrect.

2. Use ParameterizedThreadStart delegate to pass input parameters

ParameterizedThreadStart delegate is only available in .Net2.0. This delegate provides to pass an object parameter into the thread when starting the thread. This method is relatively simple to use, but because the object object needs to be typed, there is a hidden danger of type inconsistency.

3. Use thread pool to implement parameter incoming

What is a thread pool? A thread pool is a container that provides a thread storage container for the system. The thread control rights after entering the thread pool are controlled by the system. The advantage of using thread pools is that we don’t need to think about doing something else for the thread to have a lot of free time, which is suitable for routine transaction processing. In .Net, thread pool is a static class, so we need to call related functions through ThreadPool. The function that adds threads to the thread pool is (new WaitCallBack(), object obj). This function has a WaitCallBack delegate, [ComVisibleAttribute(true)]
public delegate void WaitCallback(Object state)

Through this delegation, we can also pass parameters to the thread.

In fact, there is another method that can pass parameters to a thread, which is implemented through a callback function, but this method is essentially the same as the first mechanism of passing parameters through data members of the class. So I won’t go into details!

For specific implementations, please refer to the following source code:

All source codes are as follows: (This program was compiled and passed in vs 2005)

using System;
using ;
using ;
using ;

namespace UsingThread
{
 struct RowCol
 {
  public int row;
  public int col;
 };

 class ThreadOutput
 {
  // Create waiting time  static public ManualResetEvent prompt = new ManualResetEvent(false);

  int _rowCount = 0;
  int _colCount = 0;
  char _char = '*';
  int _ret = 0;

  /**//// <summary>
   /// Input parameters
   /// </summary>
   public int RowCount
   {
    set { _rowCount = value; }
   }

   public int ColCount
   {
    set { _colCount = value; }
   }

   public char Character
   {
    set { _char = value; }
   }

   /**//// &lt;summary&gt;
  /// Output parameters  /// &lt;/summary&gt;
  public int RetVal
  {
   get { return _ret; }
  }

  public void Output()
  {
   for (int row = 0; row &lt; _rowCount; row++)
   {
    for (int col = 0; col &lt; _colCount; col++)
    {
     ("{0} ", _char);
     _ret++;
    }
    ("\n");
   }
   // Activate event   ();
  }

  public void Output(Object rc)
  {
   RowCol rowCol = (RowCol)rc;
   for (int i = 0; i &lt; ; i++)
   {
    for (int j = 0; j &lt; ; j++)
     ("{0} ", _char);
    ("\n");
   }
  }
 }

 class Program
 {
  static void Main(string[] args)
  {
   ThreadOutput to1 = new ThreadOutput();
    = 10;
    = 20;

   Thread thrd = new Thread(new ThreadStart());
   // Set as a background thread, mainly to not affect the end of the main thread    = true;
   ();

   // Create event waiting   ();

   ("{0}", );

   ThreadOutput to2 = new ThreadOutput();
    = 5;
    = 18;
    = '^';
   Thread thrds = new Thread(new ThreadStart());
    = true;
   ();
   ();

   ("{0}", );

   // Another implementation of passing parameters to thread   RowCol rc = new RowCol();
    = 12;
    = 13;
    = '@';
   if ((new WaitCallback(), rc))
    ("Insert Pool is success!");
   else
    ("Insert Pool is failed!");
   (1000);

   // Pass parameters using the new ThreadStart delegate    = 19;
    = '#';
   Thread thrdt = new Thread(new ParameterizedThreadStart());
   (rc);
   ();
  }

 }
}