C#語法基礎-04-線程
寫這兩篇文章的目的是爲了備忘、 C#語言在大學讀書時候學過、當時做過一些東西、但是由於從事的主要工作和C#無關便忘記了。 近來公司增加了Unity業務、 寫Unity主要是C# 和js 想來C# 的語法結構和Java很相似、於是採用了C#語言作爲公司遊戲項目的主要語言。
本系列主要分上中下三篇文章來記錄。 分別牽涉到C# 中的初級、中級、高級內容。
由於本月一直忙於公司的項目、 所以發文就耽擱了, 但是回想五月忙上過去了,還是整理整理髮一篇吧。
本文主要寫一些關於C#語言的高級知識, 如果沒有看過初級的,可以先看上一篇文章,在電腦上敲敲試試,跑一下看看。
- 委託方式發起線程
namespace _01_線程_委託方式發起線程 {
class Program {
//一般我們會爲比較耗時的操作 開啓單獨的線程去執行,比如下載操作
static int Test(int i,string str)
{
Console.WriteLine("test"+i+str);
Thread.Sleep(100);//讓當親線程休眠(暫停線程的執行) 單位ms
return 100;
}
static void Main(string[] args) {//在main線程中執行 一個線程裏面語句的執行 是從上到下的
//1,通過委託 開啓一個線程
//Func<int, string, int> a = Test;
//IAsyncResult ar = a.BeginInvoke(100, "siki", null, null);// 開啓一個新的線程去執行 a所引用的方法
////IAsyncResult 可以取得當前線程的狀態
////可以認爲線程是同時執行的(異步執行)
//Console.WriteLine("main");
//while (ar.IsCompleted == false)//如果當前線程沒有執行完畢
//{
// Console.Write(".");
// Thread.Sleep(10); //控制子線程的檢測頻率
//}
//int res = a.EndInvoke(ar);//取得異步線程的返回值
//Console.WriteLine(res);
//檢測線程結束
//bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);
//1000毫秒錶示超時時間,如果等待了1000毫秒 線程還沒有結束的話 那麼這個方法會返回false 如果在1000毫秒以內線程結束了,那麼這個方法會返回true
//if (isEnd)
//{
// int res = a.EndInvoke(ar);
// Console.WriteLine(res);
//}
//通過回調 檢測線程結束
//Func<int, string, int> a = Test;
//倒數第二個參數是一個委託類型的參數,表示回調函數,就是當線程結束的時候會調用這個委託指向的方法 倒數第一個參數用來給回調函數傳遞數據
//IAsyncResult ar = a.BeginInvoke(100, "siki", OnCallBack, a);// 開啓一個新的線程去執行 a所引用的方法
//a.BeginInvoke(100, "siki", ar =>
//{
// int res = a.EndInvoke(ar);
// Console.WriteLine(res+"在lambda表達式中取得");
//}, null);
Console.ReadKey();
}
static void OnCallBack( IAsyncResult ar )
{
Func<int, string, int> a = ar.AsyncState as Func<int, string, int>;
int res = a.EndInvoke(ar);
Console.WriteLine(res+"在回調函數中取得結果");
}
}
}
- 通過Thread發起線程
namespace _02_線程_通過Thread發起線程 {
class Program {
static void DownloadFile(object filename)
{
Console.WriteLine("開始下載:" +Thread.CurrentThread.ManagedThreadId +filename);
Thread.Sleep(2000);
Console.WriteLine("下載完成");
}
static void Main(string[] args) {
//Thread t = new Thread(DownloadFile);//創建出來Thread對象,這個線程並沒有啓動
//t.Start();//開始,開始去執行線程
//Console.WriteLine("Main");
//Thread t = new Thread(() =>
//{
// Console.WriteLine("開始下載:" + Thread.CurrentThread.ManagedThreadId);
// Thread.Sleep(2000);
// Console.WriteLine("下載完成");
//});
//t.Start();
//Thread t = new Thread(DownloadFile);//創建出來Thread對象,這個線程並沒有啓動
//t.Start("xxx.種子");//開始,開始去執行線程
//Console.WriteLine("Main");
//MyThread my = new MyThread("xxx.bt","http://www.xxx.bbs");
//Thread t = new Thread(my.DownFile);//我們構造一個thread對象的時候,可以傳遞一個靜態方法,也可以傳遞一個對象的普通方法
//t.Start();
//Thread t = new Thread(DownloadFile);//這個是前臺線程
Thread t = new Thread(DownloadFile);//這個是前臺線程
//t.IsBackground = true;//設置爲後臺線程
t.Start("xx");
//t.Abort();//終止這個線程的執行
t.Join();//噹噹前線程睡眠,等待t線程執行完,然後繼續運行下面的代碼
//
}
}
}
class MyThread
{
private string filename;
private string filepath;
public MyThread(string fileName, string filePath)
{
this.filename = fileName;
this.filepath = filePath;
}
public void DownFile()
{
Console.WriteLine("開始下載"+filepath+filename);
Thread.Sleep(2000);
Console.WriteLine("下載完成");
}
}
3.線程池
namespace _03_線程_線程池 {
class Program {
static void ThreadMethod(object state)
{
Console.WriteLine("線程開始:"+Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("線程結束");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(ThreadMethod);//開啓一個工作線程
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
Console.ReadKey();
}
}
}
4.線程任務
namespace _04_線程_任務 {
class Program {
static void ThreadMethod() {
Console.WriteLine("任務開始");
Thread.Sleep(2000);
Console.WriteLine("任務結束");
}
static void Main(string[] args) {
//Task t = new Task(ThreadMethod);//傳遞一個需要線程去執行的方法
//t.Start();
//TaskFactory tf = new TaskFactory();
//Task t = tf.StartNew(ThreadMethod);
Console.WriteLine("Main");
Console.ReadKey();
}
}
}
5.線程爭用問題
namespace _05_線程問題_爭用條件 {
class Program {
static void ChangeState(object o)
{
MyThreadObject m = o as MyThreadObject;
while (true)
{
lock (m)//向系統申請可不可以 鎖定m對象 如果m對象沒有被鎖定,那麼可以 如果m對象唄鎖定了,那麼這個語句會暫停,知道申請到m對象
{
m.ChangeState();//在同一時刻 只有一個線程在執行這個方法
}//釋放對m的鎖定
}
}
static void Main(string[] args) {
MyThreadObject m = new MyThreadObject();
Thread t = new Thread(ChangeState);
t.Start(m);
new Thread(ChangeState).Start(m);
Console.ReadKey();
}
}
}
- 總結
還是那句話、多思考、上手敲代碼、 調試調試、多試試。 如果有問題可以評論區留言共同學習進步。