Thread generation 04, passing data to the thread, thread name, thread Exception Handling, thread pool, 04 Exception Handling
This article describes how to pass data to a thread, how to name a thread, thread exception handling, and thread pool. It is really too basic.
□Pass data to the thread
※Use Lambda expressions
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(() => Say("hello", "world"));
t.Start();
}
static void Say(string msg, string msg1)
{
Console. WriteLine ("the first parameter value is:" + msg );
Console. WriteLine ("the second parameter value is:" + msg1 );
}
}
Note the following when using Lambda expressions.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
New Thread () => Console. WriteLine ("current Thread #" + Thread. CurrentThread. ManagedThreadId + "output value:" + I). Start ();
}
}
}
Note: Some threads share the local variable I. How can we solve the problem of thread sharing stack variables? You only need to assign an I value to a temporary variable each time you traverse the loop, and then print the Temporary Variable without directly printing the stack variable I.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
int temp = i;
New Thread () => Console. WriteLine ("current Thread #" + Thread. CurrentThread. ManagedThreadId + "output value:" + temp). Start ();
}
}
}
The printed value is not repeated.
※Start
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(Say);
t.Start("hello");
}
static void Say(object msg)
{
string str = (string) msg;
Console.WriteLine(str);
}
}
This is because the Thread constructor can receive two types of parameters.
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart (object obj);
All methods that conform to the ParameterizedThreadStart defined by the delegate must have an object-type parameter, and then pass the parameter in the instance method Start. The disadvantage of passing parameters in this way is:
1. Only one parameter can be passed
2. In the method body, the object type must be converted every time, and the box should be split.
□Name the thread
class Program
{
static void Main(string[] args)
{
Thread. CurrentThread. Name = "main Thread ";
Thread t = new Thread(Say);
T. Name = "other working threads ";
t.Start();
Say();
}
static void Say()
{
Console. WriteLine ("My Name is:" + Thread. CurrentThread. Name );
}
}
You can set or obtain the Name of the current thread and instance thread through the Name attribute.
□Thread Exception Handling
One thread cannot catch exceptions of another thread.
class Program
{
static void Main(string[] args)
{
try
{
new Thread(Say).Start();
}
catch (Exception)
{
Console. WriteLine ("exception occurred ");
}
}
static void Say()
{
throw null;
}
}
Above, the exception of another thread cannot be caught in the catch statement block of the main thread.
In fact, a thread exception must be caught in the thread method.
class Program
{
static void Main(string[] args)
{
new Thread(Say).Start();
}
static void Say()
{
try
{
throw null;
}
catch (Exception)
{
Console. WriteLine ("caught exceptions ");
}
}
}
□Thread pool
When a thread is created, the stack of the thread is created in dozens to hundreds of milliseconds. By default, each thread requires 1 MB of stack space. The thread pool achieves sharing and reuse of threads, improving performance. The thread pool can also be set to the maximum number of threads allowed. Once this limit is reached, redundant threads need to be queued and wait until the thread execution in the thread pool ends before entering.
The default maximum number of threads in the thread pool varies with the computer. In. NET 4.0 and later versions, the maximum number of threads on two computers is 1023, And the 64-bit value is 32768. in NET3.5, the maximum number of threads in the thread pool is 250. in NET2.0, the maximum number of threads in the thread pool is 25. Of course, you can use TreadPool. SetMaxThreads to set the maximum number of threads in the thread pool, or use ThreadPool. SetMinThreads to set the minimum number of threads.
The IsBackground attribute of the thread in the thread pool is true by default. This means that the main thread ends, the application ends, and the background threads in all thread pools end.
※Use TPL to enter the thread pool
TPL, Task Parallel Library, is a class Library for processing Parallel tasks.
class Program
{
static void Main(string[] args)
{
Task tast = Task.Factory.StartNew(Say);
tast.Wait();
}
static void Say()
{
Console. WriteLine ("hello, I am already a thread in the thread pool ");
}
}
Use the System. Net. WebClient instance method DownloadString to download a webpage and use a generic Task <T> for processing.
class Program
{
static void Main(string[] args)
{
Task<string> task = Task.Factory.StartNew<string>(() => DownloadString("http://www.baidu.com"));
Console. WriteLine ("when the Task is at work, I will be playing ~~ ");
Console. WriteLine ("when the Task is at work, I will be playing ~~ ");
Console. WriteLine ("when the Task is at work, I will be playing ~~ ");
string result = task.Result;
Console.WriteLine(result);
}
static string DownloadString(string uri)
{
using (var wc = new System.Net.WebClient())
{
return wc.DownloadString(uri);
}
}
}
※Do not enter the thread pool through TPL
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(Say);
ThreadPool.QueueUserWorkItem(Say, 123);
Console.ReadLine();
}
static void Say(object data)
{
Console. WriteLine ("I am from the thread pool, and the data I get is:" + data );
}
}
※Use delegate to enter the thread pool
class Program
{
static void Main(string[] args)
{
Func<string, int> method = GetLength;
IAsyncResult ia = method.BeginInvoke("test", null, null);
Console. WriteLine ("Where are the threads in the thread pool working? I will be playing first ~ ");
int result = method.EndInvoke(ia);
Console. WriteLine ("the length of test is:" + result );
}
static int GetLength(string s)
{
return s.Length;
}
}
Assign a method to the delegate variable. CLR creates a thread in the thread pool.
The thread series includes:
Thread series 01, front-end thread, back-end thread, thread synchronization thread series 02, multiple threads simultaneously process a time-consuming task to save time thread series 03, multi-thread shared data, multi-thread data sharing
Thread series 04: pass data to the thread, name the thread, handle thread exceptions, thread pool thread series 05, and manually end the thread
References: http://www.albahari.com/threading
How to name a thread in a thread pool?
Does LZ inherit and implement the execute method by itself? Or is ThreadPoolExecutor an implementation class of this abstract class provided by Java used? If ThreadPoolExecutor is used, you can check the ThreadFactory interface.
C # manage a large number of time-consuming threads, causing serious memory usage
In your statement, "the thread pool is not suitable for time-consuming tasks" is the biggest misunderstanding.
1) You must have seen many BeginXXX/EndXXX methods in the System. Net. Socket class, such as Socket. BeginReceiveFrom and Socket. EndReceiveFrom. These functions are collectively called asynchronous functions. The foundation of asynchronous function operations is the thread pool. For Socket communication, the asynchronous operations provided by Microsoft use the I/O threads in the thread pool to improve Socket I/O performance and simplify memory management!
2) If you are dizzy with asynchronous operations, you can use the "Explicit thread" method to start the processing thread as follows:
System. Thread t = new System. Thread (your processing function );
T. IsBackground = true; // This setting is especially important !!!!!
T. Start ();
Be sure to set the thread to the background thread!
3) You must know that every time the system starts and destroys a thread, it will cause a huge overhead. When your program starts and destroys threads frequently, it will inevitably cause the program to become "stuck". It is for this reason that Microsoft has created a "Thread Pool ". Because all threads in the thread are "started" (this statement is inaccurate, but there is no error ), once you mount the asynchronous processing function to the idle thread in the thread pool, you can execute the operations you want. Moreover, the additional advantage is that you do not need to manage the threads in the thread pool at all (real "zero" management)
4) Process "time-consuming operations", especially those involving Socket I/O time-consuming operations. The best solution is to use background threads (if needed, together with Custom event Events ), this is a perfect way to increase user experience ~~