Multithreaded Travel

Keywords: ASP.NET

In the last article, we already know what multithreading is, so what can it really do?In particular, here is a declaration that a former delegate who did not see the previous blog can go to the previous post to view, because multi-threaded to often use Entrust. Source code

1. Asynchronous and synchronous

*1. Synchronization (the understanding of computation is always overwhelming, synchronization happens only after a thread has done one thing), synchronization methods are slow, only one thread executes, and asynchronous methods are fast, because multiple threads work together, but they do not grow linearly. When our asynchronous threads have more and more resources, they may not be enough.Secondly, too many threads require administrative costs, so more is not better.

2. Asynchronous (can perform multiple tasks at the same time, perform different tasks at the same time), synchronous method card interface (UI) is blocked because our main thread (UI) is busy computing.Asynchronous methods do not block the interface, and the calculation task is left to the child thread to complete.Lingling's refinement reflected in winform.(Youpin, youpin), the web can handle other tasks asynchronously, such as mailboxes to users (our BS architecture, every access is a sub-thread, when our code is written poorly, is loading slower?Asynchronous multithreads are out of order, execution sequence is out of order, execution time is uncertain, and end is uncertain, so it is difficult to control the asynchronous execution order by execution time and sequence.

2. First Identity Thread

Property Name Explain
CurrentContext Gets the current context in which the thread is executing.
CurrentThread Gets the currently running thread.
ExecutionContext Gets an ExecutionContext object that contains information about the various contexts of the current thread.
IsAlive Gets a value indicating the execution state of the current thread.
IsBackground Gets or sets a value indicating whether a thread is a background thread.
IsThreadPoolThread Gets a value indicating whether a thread belongs to a managed thread pool.
ManagedThreadId Gets the unique identifier of the current managed thread.
Name Gets or sets the name of the thread.
Priority Gets or sets a value that indicates the scheduling priority of a thread.
ThreadState Gets a value that contains the state of the current thread.

Thread includes several methods to control the creation, suspension, stop, and destruction of threads, which are often used in later examples.

Method Name Explain
Abort()     Terminate this thread.
GetDomain() Returns the current domain in which the current thread is running.
GetDomainId() Returns the current domain Id in which the current thread is running.
Interrupt() Break the thread in the WaitSleepJoin thread state.
Join() Overloaded.Block the calling thread until a thread terminates.
Resume() Continue running suspended threads.
Start()   Execute this thread.
Suspend() Suspend the current thread, which does not work if it is already suspended
Sleep()   Suspend a running thread for some time.

1.Thread is a multithreaded class provided to us by.NET 1.0 that can create, control and control multithreads. The Thread class constructor accepts delegate parameters of type ThreadStart and ParameterizedThreadStart. Here is the code deity.

        /// <summary>
        /// Use Thread Create multithreads
        /// </summary>
        public static void Show()
        {
            //Instantiation creation thread has no parameters and no return value
            Thread thread = new Thread(() =>
            {
                Console.WriteLine("I am multithreaded");
            });
            thread.Start();

            //Create 5 threads 1
            for (int i = 0; i < 5; i++)
            {
                //This creates one k,Later threads are insecure and will say
                var k = i;
                //This is a multithreaded with parameters and no return values
                new Thread(x => Running(Convert.ToInt32(x))).Start(k);
            }
            Console.Read();
        }

 /// <summary>
        /// A task that takes a long time to execute
        /// </summary>
        static void Running(int s)
        {
            Console.WriteLine("**********************************");
            Console.WriteLine("Execution started" + s);
            Console.WriteLine("Get the currently executing thread ID: " + Thread.CurrentThread.ManagedThreadId.ToString());
            var j = 0;
            for (int i = 0; i < 1000000000; i++)
            {
                j++;
            }
            Console.WriteLine("Execution is over" + s);
        }

2. Entering a Better World

1. Running the code above, you can see the disorder of the threads. Although our 0 started executing first, it did not end first because of the uncertainty of the execution time of each thread.It is also important to note why the Thread constructor passes delegate parameters of type ThreadStart and ParameterizedThreadStart, why it is not Action, Func, and the answer is that Action, Func did not exist at.NET 1.0.The ThreadStart delegate is created in the code with no parameters and no return values. The ParameterizedThreadStart delegate is a parameter with no return values, but we can see that our parameter is an object type and an unsafe parameter (the generics were not there at that time). Of course, to prevent this, we also thought of a way that we could do this byA generic class to help us limit parameter types.

        /// <summary>
        /// Prevent parameter insecurity
        /// </summary>
        public static void Show5()
        {
            //We create a generic class to restrict our types
            MyThread<string> mythread = new MyThread<string>("Thread_child");
            //Pass on our methods,go in
            Thread th3 = new Thread(mythread.ThreadChild);
            //Start Thread
            th3.Start();
        }

        /// <summary>
        /// Create a generic class
        /// </summary>
        /// <typeparam name="T"></typeparam>
        class MyThread<T>
        {
            private T data;
            public MyThread(T data)
            {
                this.data = data;
            }
            public void ThreadChild()
            {
                Console.WriteLine("Child Thread Start! Result:{0}", data);
            }
        }

2. We also provide other methods above, but they are not recommended and are now discarded because we cannot precisely control the opening and pausing of threads. When we suspend threads, resources used by threads are also suspended, leading to deadlocks, which are not recommended.Destroying threads is also not recommended -- not necessarily in time/some actions cannot be received back.(Here I'm using.net Core 3.1 for direct error reporting)

        /// <summary>
        /// Use Thread Threads hang, wake, destroy by throwing exceptions, canceling Abort abnormal
        /// </summary>
        public static void Show1()
        {
            //Create a Thread thread
            Thread thread = new Thread(() =>
            {
                Running();
            });
            //Open Thread
            thread.Start();
            //This is a thread hang
            //thread.Suspend();
            //Wake Threads
            //thread.Resume();
            //The above two methods are now discarded because we cannot precisely control the opening and pausing of threads
            //When we suspend a thread, we also suspend the resources used by the thread, causing a deadlock, which is not recommended.
            try
            {
                //Destroy Threads
                //Nor is it recommended    Not necessarily in time/Some actions cannot be retrieved
                thread.Abort();
            }
            catch (Exception)
            {
                //Static method cancels thread exception to continue working
                Thread.ResetAbort();
            }
            Console.Read();
        }

3. Thread priority, of course our thread is out of order and has weight to control thread execution, but this priority is not absolute, because the order of thread execution depends on our CPU dad, but we can use Priority property to do thread weight execution, which is also very simple to use.

  /// <summary>
        /// Use Thread Thread priority (but execution still depends on) CPU,Can do priority, but not absolute priority)
        /// </summary>
        public static void Show3()
        {
            //Create a Thread thread
            Thread thread = new Thread(() =>
            {
                Running();
            });
            thread.Start();
            //thread.Priority Property sets the priority relationship of the thread
            thread.Priority = ThreadPriority.Highest;
            Console.WriteLine("Execution is over La La La La La La La La La La");
            Console.Read();
        }

4. Foreground threads, background threads (literally, or not as we understand them) We set IsBackground to control whether or not threads are (front/back) background threads.The default is the foreground thread, which must complete the task after startup to prevent the process from exiting.Specify background threads: exit with process.

3. Multi-threaded takeoff

1. Asynchronous Callback

1. Our Thread doesn't provide me with asynchronous callbacks, so I can't build my own wheels anymore. Let's first think about what callbacks need, what needs analysis is: some methods are needed after our thread tasks are executed.Let's take a closer look at the asynchronous method of synchronous execution when we're done with one person's task.How do we synchronize execution in a child thread?The following code implements the callback function, which always executes after a task no matter how many callbacks we execute.

/// <summary>
        /// Asynchronous callback execution
        /// </summary>
        public static void Show6() {
            //Create a task delegate
            ThreadStart threadStart = () => {
                Console.WriteLine("I'm Task");
            };
            //Create a callback execution delegate
            Action action = () => {
                Console.WriteLine("Ha-ha, I'm your callback method, remember double click?");
                Console.WriteLine("*********************************************");
            };
            ThreadWithCallback(threadStart, action);
            Console.ReadLine();
        }

/// <summary>
        /// Callback encapsulation has no return value
        /// </summary>
        /// <param name="start"></param>
        /// <param name="callback">Callback</param>
        private static void ThreadWithCallback(ThreadStart start, Action callback)
        {
            Thread thread = new Thread(() =>
            {
                start.Invoke();
                callback.Invoke();
            });
            thread.Start();
        }

2. Return parameters

1. Of course we need to return parameters when using threads, but our Thread doesn't give us delegates and methods to return values. What's wrong?Of course, let's analyze the requirements first. Do we want to get the return value after the thread executes?Good thread execution We can use Join to block the thread and wait for it to finish, but how do we get the return value?Yes, we can create a variable, does our thread assign a variable?

/// <summary>
        /// Asynchronous return value
        /// </summary>
        public static void Show7()
        {
            //Create a delegate
            Func<string> func = () => {
                return "I am a return value";
            };
            //Get execution results
            Console.WriteLine(ThreadWithReturn(func).Invoke());
            Console.ReadLine();
        }

/// <summary>
        /// Encapsulated with return values (encapsulate callbacks yourself in this case)
        /// </summary>
        /// <typeparam name="T">return type</typeparam>
        /// <param name="func">Methods that require subthread execution</param>
        /// <returns></returns>
        private static Func<T> ThreadWithReturn<T>(Func<T> func)
        {
            //Initialize a generic to restrict our types
            T t = default(T);
            ThreadStart newStart = () =>
            {
                //Threads assign values to variables
                t = func.Invoke();
            };
            //Create Threads
            Thread thread = new Thread(newStart);
            //Execution Thread
            thread.Start();
            //Create a delegate with no parameter return value, execution delegate will have execution thread waiting blocked
            //When the thread has finished executing, that is, the thread has given the variable t Assigned, we'll go back t
            return new Func<T>(() =>
            {
                thread.Join();
                return t;
            });
        }

4. Thread Summary

1. Do you think multithreading is cool?Ha-ha I was also a trembling hand when I was just learning.Of course, we have introduced the use of many APIs, you can try it by hand. The use of APIs is a trivial matter, the most important thing is our ideas. When we see callback encapsulation and return value encapsulation, we have used some features of multi-threading to complete these function extensions.Our macro view of multithreading is scary, but when we do the callback function, does it feel like we have a micro view of what the internal thread execution is synchronized with?Well, this is what I wrote today. I went to bed at more than 9 o'clock last night and got up early to write a nice article.Of course, multithreading has not finished before we talk about.NET 1.0 haha, and subsequent articles will be written out.

Posted by 3_Olives on Sat, 28 Mar 2020 16:58:07 -0700