一.Thread的使用方式
1.不帶參數
(1)使用lambda
public static void fun1()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ThreadStart(() =>
{
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
})).Start();
}
(2)使用方法
public static void ConsoleString()
{
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
public static void fun2()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ThreadStart(ConsoleString)).Start();
}
2.帶參數(只允許帶一個object類型參數)
public static void fun3()
{
Console.WriteLine($"Main ThreadId:{Thread.CurrentThread.ManagedThreadId}");
new Thread(new ParameterizedThreadStart(t =>
{
Console.WriteLine($"{t} Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
})).Start("haha");
}
3.等待線程執行
public static void fun4()
{
Console.WriteLine($"Main start ThreadId:{Thread.CurrentThread.ManagedThreadId}");
Thread t = new Thread(new ThreadStart(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"Thread ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}));
t.Start();
t.Join();
Console.WriteLine($"Main end ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
執行結果:

4.結束線程
Abort();
二.IsBackground講解
thread.IsBackground=true:該線程為后台線程
thread.IsBackground=true:該線程為前台線程,Thread默認為前台線程
1.前台線程和后台線程的區別
Net的公用語言運行時(Common Language Runtime,CLR)能區分兩種不同類型的線程:前台線程和后台線程。這兩者的區別就是:應用程序必須運行完所有的前台線程才可以退出;而對於后台線程,應用程序則可以不考慮其是否已經運行完畢而直接退出,所有的后台線程在應用程序退出時都會自動結束。
原理:只要所有前台線程都終止后,CLR就會對每一個活在的后台線程調用Abort()來徹底終止應用程序
2.使用建議
對於一些在后台運行的線程,當程序結束時這些線程沒有必要繼續運行了,那么這些線程就應該設置為后台線程。比如一個程序啟動了一個進行大量運算的線程,可是只要程序一旦結束,那個線程就失去了繼續存在的意義,那么那個線程就該是作為后台線程的。而對於一些服務於用戶界面的線程往往是要設置為前台線程的,因為即使程序的主線程結束了,其他的用戶界面的線程很可能要繼續存在來顯示相關的信息,所以不能立即終止它們。這里我只是給出了一些原則,具體到實際的運用往往需要編程者的進一步仔細斟酌。
一般后台線程用於處理時間較短的任務,如在一個Web服務器中可以利用后台線程來處理客戶端發過來的請求信息。而前台線程一般用於處理需要長時間等待的任務,如在Web服務器中的監聽客戶端請求的程序,或是定時對某些系統資源進行掃描的程序。
3.示例
public static void fun5()
{
Thread t1 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 50; i++)
{
Thread.Sleep(100);
Console.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t1.Start();
Thread t2 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(100);
Console.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t2.IsBackground = true;
t2.Start();
}
運行結果:
當t1執行完后,t2也不在執行,說明t1執行完成后,進程結束。
4.結束進程方式關聯
private void fun()
{
Thread t1 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 50; i++)
{
Thread.Sleep(1000);
Debug.WriteLine($"Thread1 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t1.Start();
Thread t2 = new Thread(new ThreadStart(() =>
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
Debug.WriteLine($"Thread2 {i} ThreadId:{Thread.CurrentThread.ManagedThreadId}");
}
}));
t2.IsBackground = true;
t2.Start();
}
(1)winform中:Application.Exit():所有線程都結束后(前台線程都結束后,后台線程自動結束),然后進程結束
執行 Application.Exit()
結果:等待t1執行完后,t2也不在執行,然后結束進程。
(2)Environment.Exit(0):不等待線程結束,直接結束進程
執行 Environment.Exit(0)
結果:直接結束進程,不等待線程。
參考:
https://blog.csdn.net/Fenglele_Fans/article/details/78555895
https://www.cnblogs.com/Again/articles/7085596.html
