明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

怎么創(chuàng)建與打開線程_C#線程的打開交互處理示例圖文詳細(xì)教程詳細(xì)說明

[摘要]如何創(chuàng)建和啟動(dòng)線程_C#線程的啟動(dòng)交互處理示例教程詳解 開發(fā)碰到很棘手的問題, 尋找解決方法. 品味程序出錯(cuò)過程, 逐步跟蹤程序執(zhí)行過程, 每一行代碼每一條語(yǔ)句全部執(zhí)行, 線程處理的優(yōu)點(diǎn)是可以創(chuàng)建使...

如何創(chuàng)建和啟動(dòng)線程_C#線程的啟動(dòng)交互處理示例教程詳解

開發(fā)碰到很棘手的問題, 尋找解決方法. 品味程序出錯(cuò)過程, 逐步跟蹤程序執(zhí)行過程, 每一行代碼每一條語(yǔ)句全部執(zhí)行, 線程處理的優(yōu)點(diǎn)是可以創(chuàng)建使用多個(gè)執(zhí)行線程的應(yīng)用程序。例如,某一可以具有管理與用戶交互的用戶界面線程,以及在用戶界面線程等待。

本示例講解如何創(chuàng)建和啟動(dòng)線程,并顯示了同時(shí)在同一進(jìn)程內(nèi)運(yùn)行的兩個(gè)線程間的交互。請(qǐng)注意,不必停止或釋放線程。這由公共語(yǔ)言運(yùn)行庫(kù)自動(dòng)完成。

程序從創(chuàng)建Alpha類型的對(duì)象和引用Alpha類的Beta方法的線程開始。然后啟動(dòng)該線程。線程的IsAlive屬性允許程序等待,直到線程被初始化(被創(chuàng)建、被分配等)為止。

主線程通過Thread訪問,而Sleep方法通知線程放棄其時(shí)間片并在一定毫秒數(shù)期間停止執(zhí)行。然后oThread被停止和聯(lián)接。聯(lián)接一個(gè)線程將使主線程等待它死亡或等待它在指定的時(shí)間后過期。最后,程序嘗試重新啟動(dòng)oThread,但由于線程無法在停止(中止)后重新啟動(dòng)而告失敗。有關(guān)臨時(shí)停止執(zhí)行的,請(qǐng)參見掛起線程執(zhí)行。

//StopJoin.csusingSystem;usingSystem.Threading;publicclassAlpha}};publicclassSimplecatchreturn0;}}輸出示例ThreadStart/Stop/JoinSampleAlpha.Betaisrunninginitsownthread.Alpha.Betaisrunninginitsownthread.Alpha.Betaisrunninginitsownthread.......Alpha.BetahasfinishedTrytorestarttheAlpha.BetathreadThreadStateExceptiontryingtorestartAlpha.Beta.Expectedsinceabortedthreadscannotberestarted.示例2:同步兩個(gè)線程:制造者和使用者

下面的示例顯示如何使用C#lock關(guān)鍵字和Monitor對(duì)象的Pulse方法完成同步。Pulse方法通知等待隊(duì)列中的線程對(duì)象的狀態(tài)已更改。(有關(guān)脈沖的更多詳細(xì),請(qǐng)參見Monitor.Pulse方法)。

本示例創(chuàng)建一個(gè)Cell對(duì)象,它具有兩個(gè)方法:ReadFromCell和WriteToCell。從CellProd和CellCons類創(chuàng)建另外兩個(gè)對(duì)象;這兩個(gè)對(duì)象均具有調(diào)用ReadFromCell和WriteToCell的ThreadRun方法。通過等待依次到達(dá)的來自Monitor對(duì)象的“脈沖”即可完成同步。也就是說,首先產(chǎn)生一個(gè)項(xiàng)(此時(shí)使用者等待脈沖),然后發(fā)生一個(gè)脈沖,接著使用者使用所產(chǎn)生的項(xiàng)(此時(shí)制造者等待脈沖),依此類推。

//MonitorSample.cs//ThisexampleshowsuseofthefollowingmethodsoftheC#lockkeyword//andtheMonitorclass//inthreads://Monitor.Pulse//Monitor.WaitusingSystem;usingSystem.Threading;publicclassMonitorSamplecatchcatch//EventhoughMainreturnsvoid,thisprovidesareturncodeto//theparentprocess.Environment.ExitCode=result;}}publicclassCellProdpublicvoidThreadRun}publicclassCellConspublicvoidThreadRun}publicclassCellcatchcatch}Console.WriteLine;readerFlag=false;//Resetthestateflagtosayconsuming//isdone.Monitor.Pulse;//PulsetellsCell.WriteToCellthat//Cell.ReadFromCellisdone.}//ExitsynchronizationblockreturncellContents;}publicvoidWriteToCellcatchcatch}cellContents=n;Console.WriteLine;readerFlag=true;//Resetthestateflagtosayproducing//isdoneMonitor.Pulse;//PulsetellsCell.ReadFromCellthat//Cell.WriteToCellisdone.}//Exitsynchronizationblock}}輸出示例Produce:1Consume:1Produce:2Consume:2Produce:3Consume:3......Produce:20Consume:20

[page]
 

在.net中為我們提供了兩種啟動(dòng)線程的方式,一種是不帶參數(shù)的啟動(dòng)方式,另一種是帶參數(shù)的啟動(dòng)的方式。

1:不帶參數(shù)的啟動(dòng)方式,可以使用ThreadStart來實(shí)例化Thread,ThreadStart是在.Net Framework 中已經(jīng)定義好的委托,ThreadStart定義為:

public delegate void ThreadStart();

使用方法如下面的代碼:

static void Main(string[] args)
{
Demo demo = new Demo();

Thread t = new Thread(new ThreadStart(demo.Run));
t.Name = "NoParameterThread";
t.Start();
}

public class Demo
{
int interval = 1000;
///


/// 不帶參數(shù)的啟動(dòng)方法
///

public void Run()
{
for (int i = 0; i < 10; i++)
{
DoSomething();
}
}

private void DoSomething()
{
Console.WriteLine(string.Format("當(dāng)前線程:{0},當(dāng)前系統(tǒng)時(shí)間為:{1}", Thread.CurrentThread.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
Thread.Sleep(interval);
}
}

 

2:帶參數(shù)的啟動(dòng)方法,就要使用ParameterizedThreadStart委托來實(shí)例化Thread了,和ThreadStart一樣的是它也是線程啟動(dòng)時(shí)要執(zhí)行的方法,和ThreadStart不同的是,它在實(shí)例化時(shí)可以用一個(gè)帶有一個(gè)Object參數(shù)的方法作為構(gòu)造函數(shù)的參數(shù),而實(shí)例化ThreadStart時(shí)所用到的方法是沒有參數(shù)的。ParameterizedThreadStart定義為:

public delegate void ParameterizedThreadStart(object obj);

使用方法如下面的代碼:

public class Demo
{
int interval = 1000;

private void DoSomething()
{
Console.WriteLine(string.Format("當(dāng)前線程:{0},當(dāng)前系統(tǒng)時(shí)間為:{1}", Thread.CurrentThread.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
Thread.Sleep(interval);
}

///


/// 帶參數(shù)的啟動(dòng)方法
///

///
public void Run(object param)
{
if (param == null)
return;

int.TryParse(param.ToString(), out interval);
for (int i = 0; i < 10; i++)
{
DoSomething();
}
}

}

 

static void Main(string[] args)
{
Demo demo = new Demo();

Thread parameterThread = new Thread(new ParameterizedThreadStart(demo.Run));
parameterThread.Name = "ParameterThread";
parameterThread.Start(2000);
}

3:在很多時(shí)候,我們遇到的情況是要傳遞多個(gè)參數(shù),注意到ParameterizedThreadStart委托的參數(shù)類型是一個(gè)Object對(duì)象,為什么是Object這樣的參數(shù)呢?很簡(jiǎn)單,因?yàn)樵?net中Object是所有類型的基類。這樣我們可以聲明一個(gè)類,為這個(gè)類增加屬性,這些屬性也就是參數(shù)。

使用方法如下面的代碼:

static void Main(string[] args)
{
Demo demo = new Demo();

ThreadParamter p = new ThreadParamter(2000,100);
Thread multiParameterThread = new Thread(new ParameterizedThreadStart(demo.CustomerParamterRun));
multiParameterThread.Name = "MultiParameterThread";
multiParameterThread.Start(p);
}

public class Demo
{
///


/// 帶多個(gè)參數(shù)的啟動(dòng)方法
///

///
public void CustomerParamterRun(object param)
{
if (param == null)
return;

ThreadParamter p = param as ThreadParamter;
if (p != null)
{
for (int i = 0; i < p.LoopCount; i++)
{
Console.WriteLine(string.Format("當(dāng)前線程:{0},當(dāng)前系統(tǒng)時(shí)間為:{1}", Thread.CurrentThread.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
Thread.Sleep(p.Interval);
}
}
}
}

public class ThreadParamter
{
public int Interval { get; set; }
public int LoopCount { get; set; }

public ThreadParamter()
{ }

public ThreadParamter(int interval, int loopCount)
{
this.Interval = interval;
this.LoopCount = loopCount;
}
}

 

4:在遇到業(yè)務(wù)非常復(fù)雜的時(shí)候,上面寫法還是有問題,封裝不夠好,我們可以使用裝飾模式,對(duì)上面的代碼進(jìn)行改進(jìn)。這樣業(yè)務(wù)發(fā)生改變的時(shí)候,我們只需要修改核心的實(shí)現(xiàn)部分,調(diào)用的方法可以不用做任何修改,而且調(diào)用方法的代碼非常簡(jiǎn)潔。

修改后的代碼如下:

 static void Main(string[] args)
        {
            DecoratorThread t = new DecoratorThread(new ThreadParamter(2000, 100));
            t.Start();
        }

public class ThreadParamter
{
public int Interval { get; set; }
public int LoopCount { get; set; }

public ThreadParamter()
{ }

public ThreadParamter(int interval, int loopCount)
{
this.Interval = interval;
this.LoopCount = loopCount;
}
}

///


/// 使用裝飾模式來實(shí)現(xiàn)多個(gè)參數(shù)的
///

public class DecoratorThread
{
private ThreadParamter threadParamter;
private Thread thread;


public DecoratorThread(ThreadParamter threadParamter)
{
this.threadParamter = threadParamter;
thread = new Thread(new ThreadStart(Run));
thread.Name = "DecoratorThread";
}

public void Start()
{
if (thread != null)
{
thread.Start();
}
}

private void Run()
{
for (int i = 0; i < threadParamter.LoopCount; i++)
{
Console.WriteLine(string.Format("當(dāng)前線程:{0},當(dāng)前系統(tǒng)時(shí)間為:{1}", Thread.CurrentThread.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
Thread.Sleep(threadParamter.Interval);
}
}
}

 


學(xué)習(xí)教程快速掌握從入門到精通的電腦知識(shí)