Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of Thread in C # Asynchronous Multithreading

2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article shares with you the content of the sample analysis of Thread in C # asynchronous multithreading. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

Thread API

This paper introduces some common API of Thread and uses some cases to illustrate. Because of the uncontrollability and efficiency of Thread, Thread is not commonly used now. Here we introduce some API. Students who want to go deeper can continue their research.

Instance

First look at the constructor of Thread, there are ThreadStart, ParameterizedThreadStart, maxStackSize type parameters, these three commonly used is also ThreadStart, the other two can be used as understanding.

When you look at ThreadStart and ParameterizedThreadStart in F12, you can see that ThreadStart is a delegate with no parameter type and ParameterizedThreadStart is a delegate with a parameter type. MaxStackSize is the maximum amount of memory consumed by the specified thread.

Then we create a simple case, start a thread and simulate some task lines. The code is as follows

Console.WriteLine ($"Main method start, ThreadId: {Thread.CurrentThread.ManagedThreadId}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}"); / / do some tasks Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}");}; Thread thread = new Thread (threadStart); thread.Start (); Console.WriteLine ($"Main method end, ThreadId: {Thread.CurrentThread.ManagedThreadId}"); Console.ReadLine ()

When you start the program, you can see that thread 1 (the main thread) does not wait for thread 3 (child thread) to execute the task within the anonymous method, and then execute Main to end the code. If you are using winform, it will not card the interface.

This is asynchronous multithreading, which is asynchronous because thread 1 does not wait for thread 3 to complete the task and then executes the next line in thread 1, but lets thread 3 execute without affecting thread 1 to execute the task. Multithreading is that we start a thread 3 (child thread). In the Main method, thread 1 (child thread) and thread 3 (main thread) complete the code in the Main method, which is multithreading.

When it comes to entrusting, there will be questions from small partners, why not use Action?

Because there is no Action, Func in this version, this is the product of the .net 3.0 era. Action and Func appear for unity and to solve such problems.

In the dotnet framework, it is also recommended to use Action and Func, so it is not possible to use Action here. As follows

Console.WriteLine ($"Main method start, ThreadId: {Thread.CurrentThread.ManagedThreadId}"); Action action = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}"); / / do some tasks Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}");}; ThreadStart threadStart = action;Thread thread = new Thread (threadStart); thread.Start (); Console.WriteLine ($"Main method end, ThreadId: {Thread.CurrentThread.ManagedThreadId}") Console.ReadLine ()

Suspend 、 Resume

Suspend suspend, Resume wake up, these two are a pair of corresponding API, when using these two easy to produce deadlocks, in fact, in practice should not be used, .NET framework has been abandoned, said very clearly.

Why is it deadlocked? For example, if you open a child thread 01 and read and write to the A file, you suspend the child thread 01. When you have another thread operating on the 02 A file, you will be prompted that the A file is occupied and a deadlock will be formed.

Abort 、 ResetAbort

Abort destruction, which is used by many people, is the way to throw an exception so that the destruction of child threads ends. This function is also relatively chicken, Abort child threads can not immediately stop, often there will be some delay, then this destruction sometimes can not achieve the effect that we can control.

For example, if a child thread is opened in a method for data calculation, but the execution time is too long, we have waited for 5000 ms. At this time, the Abort child thread cannot make the child thread stop computing immediately, but may have to wait a while to finish the child thread.

For example, the actions made may not be taken back. As far as querying the database is concerned, when a query command is sent to the database, we execute Abort in C #, but the command cannot be retrieved because it is at the database level, when the database query is completed, there is no thread to receive the response.

Abort is not recommended. If you use it, be sure to try catch it.

Console.WriteLine ($"Main method start, ThreadId: {Thread.CurrentThread.ManagedThreadId}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}"); / / do some tasks Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}");}; Thread thread = new Thread (threadStart); thread.Start (); try {thread.Abort () / / destroy by throwing an exception, not necessarily in time} catch (Exception ex) {/ / Thread.ResetAbort (); / / cancel the exception} Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}"); Console.ReadLine ()

Suspend, Resume and Abort are not recommended. The operation thread is suspended, terminated or other operations are uncontrollable, because the thread itself is the operating system, and CPU time-sharing and slicing will run according to its own rules. At this time, the program can no longer control it. Now that you've designed Thread, you can't be useless. Let's talk about something useful.

Join

Thread waits, Join can wait all the time, or you can set a timeout. Timeout means waiting for a certain amount of time, not waiting. While waiting, the main thread is idle and waits for the child thread to complete the task. If the winform will card the interface, the main thread waiting is also a kind of work.

For example: threadStart our simulation task takes 5 seconds, and after the thread.Start () task starts, we use thread.Join () to wait for the child thread to finish the work.

Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()});}; Thread thread = new Thread (threadStart); thread.Start (); thread.Join (); Console.WriteLine ($" Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()} "); Console.ReadLine ()

Starting the program, you can see that it is the result we want (like synchronous execution), and the main thread 1 has been waiting for child thread 3 to complete the task. If it is winform, the interface will be stuck, although thread.Join () main thread 1 will wait for child thread 3 to finish its work, but main thread 1 waiting is also a kind of work.

Then let's take a look at timeout waiting, the overloading method of Join.

For example: threadStart, it takes 5 seconds to simulate the task. After the thread.Start () task starts, we use thread.Join (3x1000) to let the main thread wait for the child thread for up to 3 seconds. If the child thread does not finish the task for 3 seconds, it will not wait.

Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.Start (); thread.Join (3 * 1000); Console.WriteLine ($"Main method end, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); Console.ReadLine ()

When the program is started, main thread 1 starts the task, and child thread 3 starts the task. When the child thread executes 3 seconds (during which main thread 1 is waiting), main thread 3 starts to execute the task.

Note: thread.Join (n * 1000) does not necessarily wait that long, but waits at most, during which the child thread does not wait after the task is completed.

For example, the threadStart task method simulates 5 s thread.Join (7 * 1000) the main thread waits for 7 s

Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.Start (); thread.Join (7 * 1000); Console.WriteLine ($"Main method end, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); Console.ReadLine ()

ThreadState

Thread state, ThreadState can also do thread waiting, waiting for the main thread to be idle while waiting for the child thread to complete the task. If the winform will card the interface, the main thread waiting is also a kind of work.

Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.Start (); while (thread.ThreadState! = ThreadState.Stopped) {Thread.Sleep / / current thread rest 200ms} Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); Console.ReadLine ()

Sleep

The thread is paused and the current thread of Sleep is paused. If it is winform, the interface will be stuck, when Sleep, CPU shards will be handed over, and the main thread is not in the working state.

Console.WriteLine ($"Main method start, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); Thread.Sleep (5 * 1000); / / Simulation task takes 5 seconds Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); Console.ReadLine ()

IsBackground

Whether it is a background thread, when the instance Thread, the default is the foreground thread (IsBackground = = false). The foreground thread must complete the task before it lets the process exit. The background thread (IsBackground = = true) ends with the end of the process, regardless of whether the child thread task is completed or not.

Foreground thread, that is, when we start a program, when we close the program, if there are child threads to execute the task, the current process will not quit and will wait for the child process to complete the task, that is, it will prevent the process from ending, and vice versa.

For example, after the foreground thread starts the console, after the main thread finishes executing the task, the window will not be closed until the child thread's task is completed (5s).

Static void Main (string [] args) {Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.Start (); while (thread.ThreadState! = ThreadState.Stopped) {Thread.Sleep / / current thread rest 200ms} Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}

For example: background thread, after starting the console, the window will be closed immediately after the task of the main thread is executed.

Static void Main (string [] args) {Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.IsBackground = true; thread.Start (); Console.WriteLine ($"thread IsBackground: {thread.IsBackground}, DateTime: {DateTime.Now.ToLongTimeString ()}") Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");} Priority

A thread can set a priority, and when a thread is assigned a priority from high to low, it will be given priority when applying for a thread from CPU. However, this feature is also quite chubby. For CPU, when they come at the same time, they will only slice the high priority parts first, but the low priority ones will not be assigned, nor does it mean that the high priority ones will be completed first, which also depends on the amount of tasks to be executed. In fact, priority is useless, multithreading is inherently unordered.

Console.WriteLine ($"Main method starts, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); ThreadStart threadStart = () = > {Console.WriteLine ($"Task Start ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); / / do some tasks Thread.Sleep (5 * 1000) / / the simulation task takes 5 seconds Console.WriteLine ($"Task End ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}");}; Thread thread = new Thread (threadStart); thread.Priority = ThreadPriority.Highest;// CPU will be executed first, it does not mean that Highest will give priority to thread.Start (); Console.WriteLine ($"thread IsBackground: {thread.IsBackground}, DateTime: {DateTime.Now.ToLongTimeString ()}") Console.WriteLine ($"Main method ends, ThreadId: {Thread.CurrentThread.ManagedThreadId}, DateTime: {DateTime.Now.ToLongTimeString ()}"); thank you for reading! This is the end of this article on "sample Analysis of Thread in C# Asynchronous Multithreading". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it out for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report