Advanced_C#_Skill_What is thread,background thread and foreground thread ?_Parallel code execution

There are two important types of threads



1. background thread 


2. foreground thread


Threading in C# means Parallel(平行的、並行的) code execution.

平行處理、並行進程

Parallel Processing
平行計算
Parallel Computing










一個人可以同時一手打電腦、一手打電話、一腳彈鋼琴、一腳打鼓
一隻眼看電腦、一隻眼看電視


可以同時一次運行、做好多事情

這就是多執行緒(平行的)概念


Process(行程)是指證在執行中的程式
包含了

存放在 Memory Space 的
(1)Code Section(程式碼、程式區間)
(2)Data Section(資料區間)
(3)Program Counter(程式計數器)
(4)CPU Register(程式計數器)
(5)Stack
多個process之間會相互que來que去及做遞迴工作,用以存放返回位址。


Process 為 OS 分配資源的主要對象!!!!!!

我們需要靠 OS 去做控管 

例如規劃這個process 做3分鐘 另一個做5分鐘....等等




在傳統的 單執行緒(Process) 重量級行程
就等同於一個Task(Process) 內 只有單一個Thread。



執行緒(又有 "線程" 的說法)

左側只能執行一個工作 ,  右側能執行兩個工作。

        (Process)                        (Thread)


一個Process它可以執行一個任務(工作),
他必須要有自己的code section、自己的Data Section、自己的stack、register等等
這些相關資源全部自己要背負,她才可以去正常執行一個任務。


Thread 可有多個,一個執行緒做一份工,各自有自己的register、stack
至於其他的 code section、 data section可以共用,不用自己生成一份。


以OS角度若每次我要執行一個新的工作,若是process,他必須自己一個人背負
程式、資料、檔案相關資訊。 消耗記憶體就大!!!

所以 Thread 的好處就是 資料是可以共用的!!!!


「火車站的訂票系統」在北 中 南 都可以用!!
基本上 程式碼 、資料檔、openfile都會是一樣的

假設今天  台北、高雄、台中都有一個人同時訂票
如果我都是產生process的話,此時對於我系統的執行來說。
他所花費的resource是較高的。

因為每一個process 的 code section、data section 、file都要自己有一份!

可是這些東西都是一樣的其實可以共享的~~

所以通常這種訂票系統會採用 thread的做法。

各自給 台北那個人、台中那個人、高雄那個人各一條thread去做
訂票的動作,這樣系統所要耗費的資源相對來講較低。


Process 可以把它視為 Single Thread

In order to understand how C# actually runs these codes parallely


Let's create a simple console application in C# and let see a simple example and llets demonstrate threading




After executed the program , you can see from the program that first function1 runs

and then function2 runs so in other words it is a synchronous(同步) processing.


Synchronous means sequential(循序的) processing in other words until function 1 does not finish , function 2 does not start.


Now there can be satiation where would like to run both of these functions parallely .

In other words , you would like to have some kind of mechanism(機制) where you would like to say OK.

function1 and function2 both of you guise will run parellely in other words

you would like your computer processor to give some time to function1 and then some time to function2 so rather than executing sequentially you would like to see here function1 executed one and the function2 executed and then again function1 executed and that's where we use threading .


So let's go step by step and let see how we can implement threading
in this project.

At first you need to  

   using System.Threading


this is the namespace where you have a thread object which helps
you to execute function or your logic parellely also rather that invoking these function sequentially we would like to go and invoke them in a multi threaded manner or in a parallel way right in order to invoke function1 and function2 in parallel way we need to use something called as the thread object.

so let me go and create a thread object



Now in this thread object you need to pass the parameter which is nothing but the function name so I am going to say OK

This thread on this thread will actually go and run function1 



and will get one more thread object here called as obj2 which will actually run function2 right so we have created two thread objects




So that both of these function can run parallely one is obj1 and other one is obj2 


obj1 points towards function1 and obj2 point towards function2 and the next thing is we need to go and start both of these thread so we can say obj1 start so this actually goes and invokes a separate thread on which function1 will actually start executing and we would also like to go and start a second thread on which we go to run function2 


so we first went ahead and created two threads one for function1 and the other one for function2 

and then is the next step be invoked these threads 

In order to see a clear execution what I will do is after every for loop which runs right every for variable executed inside function1 as well as function2




I will wait for must be for 4 seconds now in order to wait for 4 seconds I am go to again use the thread class here 



and I am going to say here thread.sleep and you can see that we need to pass here milliseconds so I am go to say 4 thounsands so 

1 second = 1000millissecond so we can go to here for 4 second and also
I would like to wait even in function2 for every for loop execution again

for 4 seconds so that  you can see this output clearly.


How there executing in multi threaded manner or in a parallel manner so 
we have written the complete application .

Now you have created two thread objects attached with function1 and finction2 and second as the for loop is running we went to for 4 second to see how the output actually looks like.

and now let me just do a ctrl+F5 here and you can clearly see that function2 has executed first !!!



It is running both of these functions parallel or I will say rather in the multi threaded manner

So that what is the use of threading by using threading you can execute programming codes in a
multi-threaded way or in a parallel way .


實際執行影片結果:




第一階段程式碼


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Multithreading_with_timer_ex1
{
    class Program
    {
        static void Main(string[] args)
        {
            //synchronous(同步的) = sequential(循序的) processing
            //Function1();
            //Function2();

            //Parallel(平行的) code execution
            //Step1.Create two thread
            Thread obj1 = new Thread(Function1);
            Thread obj2 = new Thread(Function2);
            //Step2.invoke(調用) these threads
            obj1.Start();
            obj2.Start();                        
            Console.ReadKey();//卡住
            //if your application quit
        }
        static void Function1()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Function 1 executed" +i.ToString());
                // wait for 4 seconds
                Thread.Sleep(4000);
            }            
        }
        static void Function2()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("Function 2 executed" +i.ToString());
                // wait for 4 seconds
                Thread.Sleep(4000);
            }
        }
    }
}








At the beginning we have made an issue of  something about kinds of threading

There are two kinds of threading:

One is the foreground thread and the other one is the background thread

Now whatever thread object we have created are type of foreground thread so by default when ever you  create thread like this its a foreground thread so both of these thread that is obj1 and obj2 are foreground threads.

執行緒可分為  前景執行緒 與 背景執行緒 兩種,
在預設的狀況下Thread是屬於前景執行緒
也就是
Thread.IsBackground=false

若主程序已下達中止工作命令了,
有任一前景執行緒尚未完成工作,程序不會立即中止,
需待前景執行緒完成工作後才會終止。


What exactly the foreground thread


Foreground threads are thread which will keep running even though(即使) if your main application exits or main application quits


in other words our main application starts from static void main so that's are main thread .


Now even if your main application quits over here
like this is the point when main application will quit



then also your foreground threads will execute until the finished that there task .



Now let's talk about background thread .

Background thread are threads which will quit if your main application quit 

so in other words until your main application is alive the background thread is alive .
the time your main application quits even the background thread quits.


反之,背景執行緒不管工作有沒有完成,
一但收到中止命令,馬上就停下手邊的工作中止工作。



Now what will do is let's go and do a simple sample demonstration understand both of these concepts in a practical manner so what will do is let's make this code more simple so I am going to and delete

function2 over here I am go to only this function1 and only thread for that so all of the threads .



Just delete it so very simple application here we have only one thread and this thread actually goes and response function1 and in this what I will do is I am to put the Console.Write here Function1 is executing 



and here what I will do is I am going to do a Console.ReadLine() here 




Foreground threads影片實例



Foreground threads程式碼


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Multithreading_with_timer_ex1
{
    class Program
    {
        static void Main(string[] args)
        {
            // A thread will be created to run 
            //function1 parallely
            Thread obj1 = new Thread(Function1);
            obj1.Start();

            //the control will come here exit the main function
            Console.WriteLine("The main application has exited");                       
        }
        static void Function1()
        {
            Console.WriteLine("Function 1 entered.....");
            //wait here until the user put any input 
            Console.ReadLine();//wait here
            Console.WriteLine("Function 1 is exited.....");
        }

    }
}



Background thread影片實例





Background thread程式碼

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Multithreading_with_timer_ex1
{
    class Program
    {
        static void Main(string[] args)
        {
            // A thread will be created to run 
            //function1 parallely
            Thread obj1 = new Thread(Function1);
            obj1.IsBackground = true;
            obj1.Start();

            //the control will come here exit the main function
            Console.WriteLine("The main application has exited");
            //Console.ReadKey();                     
        }
        static void Function1()
        {
            Console.WriteLine("Function 1 entered.....");
            //wait here until the user put any input 
            Console.ReadLine();//wait here
            Console.WriteLine("Function 1 is exited.....");
        }

    }
}







在多執行緒(線程)編程中,
我們經常要在工作執行緒(線程)中去更新介面顯示,
而在多執行緒(線程)中直接調用介面控制元件的方法是錯誤的做法

InvokeBeginInvoke 就是為了解決這個問題而出現的,
使你在多執行緒(線程)中安全的更新介面顯示。


正確的做法是將工作執行緒(線程)中涉及更新介面的程式碼
封裝為一個方法(method),
通過 Invoke 或者 BeginInvoke 去呼叫
兩者的區別就是一個導致工作執行緒(線程)等待,而另外一個則不會。


而所謂的"一面響應操作,一面添加節點" 永遠只能是相對的,
使 UI 執行緒(線程)的負擔不至於太大而已,
因為介面的正確更新始終要通過 UI執行緒(線程)去做,

我們要做的事情是在工作執行緒(線程)中囊括大部分的運算,
而將對純粹的介面更新放到 UI執行緒(線程)中去做,
這樣也就達到了減輕 UI 執行緒(線程)負擔的目的了。



以下例子說明下使用方法method,比如你在呼叫一個執行緒(線程),
在執行緒(線程)的方法中想更新Form中的一個TextBox.


using System.Threading; 

//啟動一個執行緒(線程) 
Thread thread=new Thread(new ThreadStart(DoWork)); 
thread.Start(); 

//執行緒(線程)方法 
private void DoWork() 
{ 
     this.TextBox1.Text="我是一個Textbox"; 
} 

如果你像上面操作,在VS2005或2008裡是會有異常的... 

正確的做法是用Invoke/BeginInvoke


using System.Threading;
namespace test
{
    public partial class Form1 : Form
    {
        public delegate void MyInvoke(string str1,string str2);
        public Form1()
        {
            InitializeComponent();

 }
        public void DoWork()
        {
             MyInvoke mi = new MyInvoke(UpdateForm);
             this.BeginInvoke(mi, new Object[] {"我是Textbox","haha"});
        }
        public void UpdateForm(string param1,string parm2)
        {
            this.textBox1.Text = param1+parm2;
        }

        private void button1_Click(object sender, EventArgs e)
        {
             Thread thread = new Thread(new ThreadStart(DoWork));
             thread.Start();
        }
    }
}

->注意委派(代理)的使用!

基本上delegate(委派)是一種型別安全(Type-Safe)的函式指標,
他可以對於某個方法進行同步叫用,
但對於獨立的執行緒中他是以非同步的方法來叫用。



至於 Invoke則是用來叫用委派的方法,
委派另外還提供了兩個呼叫非同步的方法
BeginInvoke及EndInvoke,
其中BeginInvoke又 會傳回一個IAsyncResult。






至於程式碼您可以參考一下MSDN文件庫:(裡面有範例程式碼及詳細說明)
事件和委派
http://msdn.microsoft.com/zh-tw/library/17sde2xt(VS.80).aspx

在建立控制項基礎控制代碼的執行緒上執行指定的非同步委派。

http://msdn.microsoft.com/zh-tw/library/0b1bf3y3(VS.85).aspx


學自:

c# (Csharp) threading interview question:- 
What is thread,background thread and foreground thread ?

https://www.youtube.com/watch?v=Fzckqczmgd0


杰哥數位教室作業系統課程

http://sjchen.im.nuu.edu.tw/OS_Final.html


[轉載]C# Invoke的用法

http://blog.xuite.net/merci0212/wretch/141175679-%5B%E8%BD%89%E8%BC%89%5DC%23+Invoke%E7%9A%84%E7%94%A8%E6%B3%95


The word 'issue' 單詞用法詳解
http://www.bbc.com/ukchina/trad/elt/study_and_exams/2014/11/141127_qanda_320_issue

余小章 @ 大內殿堂 [C#.NET][Thread] 背景執行緒與前景執行緒的差別 https://dotblogs.com.tw/yc421206/2011/01/04/20574

留言

這個網誌中的熱門文章

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header

經得起原始碼資安弱點掃描的程式設計習慣培養(三)_7.Cross Site Scripting(XSS)_Stored XSS_Reflected XSS All Clients

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題