欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談C#多線程簡(jiǎn)單例子講解

 更新時(shí)間:2016年12月03日 14:20:10   作者:C#教程  
本篇文章主要介紹了C#多線程簡(jiǎn)單例子,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

.NET將關(guān)于多線程的功能定義在System.Threading名字空間中。因此,要使用多線程,必須先聲明引用此名字空間(using System.Threading;)。

a.啟動(dòng)線程

顧名思義,“啟動(dòng)線程”就是新建并啟動(dòng)一個(gè)線程的意思,如下代碼可實(shí)現(xiàn):

Thread thread1 = new Thread(new ThreadStart( Count));

其中的 Count 是將要被新線程執(zhí)行的函數(shù)。

b.殺死線程

“殺死線程”就是將一線程斬草除根,為了不白費(fèi)力氣,在殺死一個(gè)線程前最好先判斷它是否還活著(通過(guò) IsAlive 屬性),然后就可以調(diào)用 Abort 方法來(lái)殺死此線程。

c.暫停線程

它的意思就是讓一個(gè)正在運(yùn)行的線程休眠一段時(shí)間。如 thread.Sleep(1000); 就是讓線程休眠1秒鐘。

d.優(yōu)先級(jí)

這個(gè)用不著解釋了。Thread類中hreadPRiority屬性,它用來(lái)設(shè)置優(yōu)先級(jí),但不能保證操作系統(tǒng)會(huì)接受該優(yōu)先級(jí)。一個(gè)線程的優(yōu)先級(jí)可分為5種:Normal, AboveNormal, BelowNormal, Highest, Lowest。具體實(shí)現(xiàn)例子如下:

thread.Priority = ThreadPriority.Highest;

e.掛起線程

Thread類的Suspend方法用來(lái)掛起線程,直到調(diào)用Resume,此線程才可以繼續(xù)執(zhí)行。如果線程已經(jīng)掛起,那就不會(huì)起作用。

if (thread.ThreadState = ThreadState.Running) 
{
thread.Suspend();
}

f.恢復(fù)線程

用來(lái)恢復(fù)已經(jīng)掛起的線程,以讓它繼續(xù)執(zhí)行,如果線程沒(méi)掛起,也不會(huì)起作用。

if (thread.ThreadState = ThreadState.Suspended) 
{
thread.Resume();
}

下面將列出一個(gè)例子,以說(shuō)明簡(jiǎn)單的線程處理功能。此例子來(lái)自于幫助文檔。

using System;
using System.Threading;

// Simple threading scenario: Start a static method running
// on a second thread.
public class ThreadExample {
// The ThreadProc method is called when the thread starts.
// It loops ten times, writing to the console and yielding 
// the rest of its time slice each time, and then ends.
public static void ThreadProc() {
for (int i = 0; i < 10; i++) {
Console.WriteLine("ThreadProc: {0}", i);
// Yield the rest of the time slice.
Thread.Sleep(0);
}
}

public static void Main() {
Console.WriteLine("Main thread: Start a second thread.");
// The constructor for the Thread class requires a ThreadStart 
// delegate that represents the method to be executed on the 
// thread. C# simplifies the creation of this delegate.
Thread t = new Thread(new ThreadStart(ThreadProc));
// Start ThreadProc. On a uniprocessor, the thread does not get 
// any processor time until the main thread yields. Uncomment 
// the Thread.Sleep that follows t.Start() to see the difference.
t.Start();
//Thread.Sleep(0);

for (int i = 0; i < 4; i++) {
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(0);
}

Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.");
t.Join();
Console.WriteLine("Main thread: ThreadProc.Join has returned. Press Enter to end program.");
Console.ReadLine();
}
}

此代碼產(chǎn)生的輸出類似如下內(nèi)容:

Main thread: Start a second thread.
Main thread: Do some work.
ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Call Join(), to wait until ThreadProc ends.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
Main thread: ThreadProc.Join has returned. Press Enter to end program.

在Visul C#中System.Threading 命名空間提供一些使得可以進(jìn)行多線程編程的類和接口,其中線程的創(chuàng)建有以下三種方法:Thread、ThreadPool、Timer。下面就它們的使用方法逐個(gè)作一簡(jiǎn)單介紹。

一、Thread

這也許是最復(fù)雜的方法,但它提供了對(duì)線程的各種靈活控制。首先你必須使用它的構(gòu)造函數(shù)創(chuàng)建一個(gè)線程實(shí)例,它的參數(shù)比較簡(jiǎn)單,只有一個(gè)ThreadStart 委托:public Thread(ThreadStart start);然后調(diào)用Start()啟動(dòng)它,當(dāng)然你可以利用它的Priority屬性來(lái)設(shè)置或獲得它的運(yùn)行優(yōu)先級(jí)(enum ThreadPriority: Normal、 Lowest、 Highest、 BelowNormal、 AboveNormal)。

下例首先生成了兩個(gè)線程實(shí)例t1和t2,然后分別設(shè)置它們的優(yōu)先級(jí),接著啟動(dòng)兩線程(兩線程基本一樣,只不過(guò)它們輸出不一樣,t1為“1”,t2為“2”,根據(jù)它們各自輸出字符個(gè)數(shù)比可大致看出它們占用CPU時(shí)間之比,這也反映出了它們各自的優(yōu)先級(jí))。

static void Main(string[] args)
{
 Thread t1 = new Thread(new ThreadStart(Thread1));
 Thread t2 = new Thread(new ThreadStart(Thread2));

 t1.Priority = ThreadPriority.BelowNormal ;
 t2.Priority = ThreadPriority.Lowest ;
   t1.Start();
  t2.Start();
 }
public static void Thread1()
{ 
 for (int i = 1; i < 1000; i++) 
 {//每運(yùn)行一個(gè)循環(huán)就寫(xiě)一個(gè)“1”
  dosth();
 Console.Write("1");
 }
 }
public static void Thread2()
{ 
 for (int i = 0; i < 1000; i++) 
 {//每運(yùn)行一個(gè)循環(huán)就寫(xiě)一個(gè)“2”
 dosth();
 Console.Write("2");
 }
}
public static void dosth()
{//用來(lái)模擬復(fù)雜運(yùn)算
 for (int j = 0; j < 10000000; j++) 
 { 
 int a=15;
 a = a*a*a*a;
 }
}

以上程序運(yùn)行結(jié)果為:

11111111111111111111111111111111111111111121111111111111111111111111111111111111111112
11111111111111111111111111111111111111111121111111111111111111111111111111111111111112
11111111111111111111111111111111111111111121111111111111111111111111111111111111111112

從以上結(jié)果我們可以看出,t1線程所占用CPU的時(shí)間遠(yuǎn)比t2的多,這是因?yàn)閠1的優(yōu)先級(jí)比t2的高,若我們把t1和t2的優(yōu)先級(jí)都設(shè)為Normal,結(jié)果見(jiàn)下:

121211221212121212121212121212121212121212121212121212121212121212121
212121212121212121212121212121212121212121212121212121212121212121212
121212121212121212

從上例我們可看出,它的構(gòu)造類似于win32的工作線程,但更加簡(jiǎn)單,只需把線程要調(diào)用的函數(shù)作為委托,然后把委托作為參數(shù)構(gòu)造線程實(shí)例即可。當(dāng)調(diào)用Start()啟動(dòng)后,便會(huì)調(diào)用相應(yīng)的函數(shù),從那函數(shù)第一行開(kāi)始執(zhí)行。

接下來(lái)我們結(jié)合線程的ThreadState屬性來(lái)了解線程的控制。ThreadState是一個(gè)枚舉類型,它反映的是線程所處的狀態(tài)。當(dāng)一個(gè)Thread實(shí)例剛創(chuàng)建時(shí),它的ThreadState是Unstarted;當(dāng)此線程被調(diào)用Start()啟動(dòng)之后,它的ThreadState是 Running;  在此線程啟動(dòng)之后,如果想讓它暫停(阻塞),可以調(diào)用Thread.Sleep() 方法,它有兩個(gè)重載方法(Sleep(int )、Sleep(Timespan )),只不過(guò)是表示時(shí)間量的格式不同而已,當(dāng)在某線程內(nèi)調(diào)用此函數(shù)時(shí),它表示此線程將阻塞一段時(shí)間(時(shí)間是由傳遞給 Sleep 的毫秒數(shù)或Timespan決定的,但若參數(shù)為0則表示掛起此線程以使其它線程能夠執(zhí)行,指定 Infinite 以無(wú)限期阻塞線程),此時(shí)它的ThreadState將變?yōu)閃aitSleepJoin,另外值得注意一點(diǎn)的是Sleep()函數(shù)被定義為了static?! 這也意味著它不能和某個(gè)線程實(shí)例結(jié)合起來(lái)用,也即不存在類似于t1.Sleep(10)的調(diào)用!正是如此,Sleep()函數(shù)只能由需“Sleep”的線程自己調(diào)用,不允許其它線程調(diào)用,正如when to Sleep是個(gè)人私事不能由它人決定。但是當(dāng)某線程處于WaitSleepJoin狀態(tài)而又不得不喚醒它時(shí),可使用Thread.Interrupt 方法 ,它將在線程上引發(fā)ThreadInterruptedException,下面我們先看一個(gè)例子(注意Sleep的調(diào)用方法):

static void Main(string[] args)
{ 
 Thread t1 = new Thread(new ThreadStart(Thread1));
 t1.Start();
  t1.Interrupt ();
  E.WaitOne ();
  t1.Interrupt ();
   t1.Join();
   Console.WriteLine(“t1 is end”);
}
static AutoResetEvent E = new AutoResetEvent(false);
public static void Thread1()
{ 
 try
 {//從參數(shù)可看出將導(dǎo)致休眠
 Thread.Sleep(Timeout.Infinite); 
 }
 catch(System.Threading.ThreadInterruptedException e)
 {//中斷處理程序
 Console.WriteLine (" 1st interrupt");
 }
  E.Set ();
 try
 {// 休眠
 Thread.Sleep(Timeout.Infinite ); 
 }
 catch(System.Threading.ThreadInterruptedException e)
 {
  Console.WriteLine (" 2nd interrupt");
 }//暫停10秒
   Thread.Sleep (10000); 
  }

運(yùn)行結(jié)果為:

1st interrupt
 2nd interrupt
 (10s后)t1 is end

從上例我們可以看出Thread.Interrupt方法可以把程序從某個(gè)阻塞(WaitSleepJoin)狀態(tài)喚醒進(jìn)入對(duì)應(yīng)的中斷處理程序,然后繼續(xù)往下執(zhí)行(它的ThreadState也變?yōu)镽unning),此函數(shù)的使用必須注意以下幾點(diǎn):

1、此方法不僅可喚醒由Sleep導(dǎo)致的阻塞,而且對(duì)一切可導(dǎo)致線程進(jìn)入WaitSleepJoin狀態(tài)的方法(如Wait和Join)都有效。如上例所示, 使用時(shí)要把導(dǎo)致線程阻塞的方法放入try塊內(nèi), 并把相應(yīng)的中斷處理程序放入catch塊內(nèi)。

2、對(duì)某一線程調(diào)用Interrupt, 如它正處于WaitSleepJoin狀態(tài), 則進(jìn)入相應(yīng)的中斷處理程序執(zhí)行, 若此時(shí)它不處于WaitSleepJoin狀態(tài), 則它后來(lái)進(jìn)入此狀態(tài)時(shí), 將被立即中斷。若在中斷前調(diào)用幾次Interrupt, 只有第一次調(diào)用有效, 這正是上例我用同步的原因, 這樣才能確保第二次調(diào)用Interrupt在第一個(gè)中斷后調(diào)用,否則的話可能導(dǎo)致第二次調(diào)用無(wú)效(若它在第一個(gè)中斷前調(diào)用)。你可以把同步去掉試試,其結(jié)果很可能是:   1st interrupt

上例還用了另外兩個(gè)使線程進(jìn)入WaitSleepJoin狀態(tài)的方法:利用同步對(duì)象和Thread.Join方法。Join方法的使用比較簡(jiǎn)單,它表示在調(diào)用此方法的當(dāng)前線程阻塞直至另一線程(此例中是t1)終止或者經(jīng)過(guò)了指定的時(shí)間為止(若它還帶了時(shí)間量參數(shù)),當(dāng)兩個(gè)條件(若有)任一出現(xiàn),它立即結(jié)束WaitSleepJoin狀態(tài)進(jìn)入Running狀態(tài)(可根據(jù).Join方法的返回值判斷為何種條件,為true,則是線程終止;false則是時(shí)間到)。線程的暫停還可用Thread.Suspend方法,當(dāng)某線程處于Running狀態(tài)時(shí)對(duì)它調(diào)用Suspend方法,它將進(jìn)入SuspendRequested狀態(tài),但它并不會(huì)被立即掛起,直到線程到達(dá)安全點(diǎn)之后它才可以將該線程掛起,此時(shí)它將進(jìn)入Suspended狀態(tài)。如對(duì)一個(gè)已處于Suspended的線程調(diào)用則無(wú)效,要恢復(fù)運(yùn)行只需調(diào)用Thread.Resume即可。

最后我們談的是線程的銷毀,我們可以對(duì)需銷毀的線程調(diào)用Abort方法,它會(huì)在此線程上引發(fā)ThreadAbortException。我們可把線程內(nèi)的一些代碼放入try塊內(nèi),并把相應(yīng)處理代碼放入相應(yīng)的catch塊內(nèi),當(dāng)線程正執(zhí)行try塊內(nèi)代碼時(shí)如被調(diào)用Abort,它便會(huì)跳入相應(yīng)的catch塊內(nèi)執(zhí)行,執(zhí)行完catch快內(nèi)的代碼后它將終止(若catch塊內(nèi)執(zhí)行了ResetAbort則不同了:它將取消當(dāng)前Abort請(qǐng)求,繼續(xù)向下執(zhí)行。所以如要確保某線程終止的最好用Join,如上例)。

二、ThreadPool

線程池(ThreadPool)是一種相對(duì)較簡(jiǎn)單的方法,它適應(yīng)于一些需要多個(gè)線程而又較短任務(wù)(如一些常處于阻塞狀態(tài)的線程) ,它的缺點(diǎn)是對(duì)創(chuàng)建的線程不能加以控制,也不能設(shè)置其優(yōu)先級(jí)。由于每個(gè)進(jìn)程只有一個(gè)線程池,當(dāng)然每個(gè)應(yīng)用程序域也只有一個(gè)線程池(對(duì)線),所以你將發(fā)現(xiàn)ThreadPool類的成員函數(shù)都為static! 當(dāng)你首次調(diào)用ThreadPool.QueueUserWorkItem、ThreadPool.RegisterWaitForSingleObject等,便會(huì)創(chuàng)建線程池實(shí)例。下面就線程池當(dāng)中的兩函數(shù)作一介紹:

public static bool QueueUserWorkItem( //調(diào)用成功則返回true
WaitCallback callBack,//要?jiǎng)?chuàng)建的線程調(diào)用的委托
  object state //傳遞給委托的參數(shù)
)//它的另一個(gè)重載函數(shù)類似,只是委托不帶參數(shù)而已

此函數(shù)的作用是把要?jiǎng)?chuàng)建的線程排隊(duì)到線程池,當(dāng)線程池的可用線程數(shù)不為零時(shí)(線程池有創(chuàng)建線程數(shù)的限制,缺身值為25),便創(chuàng)建此線程,否則就排隊(duì)到線程池等到它有可用的線程時(shí)才創(chuàng)建。

public static RegisteredWaitHandle RegisterWaitForSingleObject(
 WaitHandle waitObject,// 要注冊(cè)的 WaitHandle
 WaitOrTimerCallback callBack,// 線程調(diào)用的委托
 object state,//傳遞給委托的參數(shù)
 int TimeOut,//超時(shí),單位為毫秒,
 bool executeOnlyOnce file://是否只執(zhí)行一次
); 
public delegate void WaitOrTimerCallback(
 object state,//也即傳遞給委托的參數(shù)
 bool timedOut//true表示由于超時(shí)調(diào)用,反之則因?yàn)閣aitObject
);

此函數(shù)的作用是創(chuàng)建一個(gè)等待線程,一旦調(diào)用此函數(shù)便創(chuàng)建此線程,在參數(shù)waitObject變?yōu)榻K止?fàn)顟B(tài)或所設(shè)定的時(shí)間TimeOut到了之前,它都處于“阻塞”狀態(tài),值得注意的一點(diǎn)是此“阻塞”與Thread的WaitSleepJoin狀態(tài)有很大的不同:當(dāng)某Thread處于WaitSleepJoin狀態(tài)時(shí)CPU會(huì)定期的喚醒它以輪詢更新?tīng)顟B(tài)信息,然后再次進(jìn)入WaitSleepJoin狀態(tài),線程的切換可是很費(fèi)資源的;而用此函數(shù)創(chuàng)建的線程則不同,在觸發(fā)它運(yùn)行之前,CPU不會(huì)切換到此線程,它既不占用CPU的時(shí)間又不浪費(fèi)線程切換時(shí)間,但CPU又如何知道何時(shí)運(yùn)行它?實(shí)際上線程池會(huì)生成一些輔助線程用來(lái)監(jiān)視這些觸發(fā)條件,一旦達(dá)到條件便啟動(dòng)相應(yīng)的線程,當(dāng)然這些輔助線程本身也占用時(shí)間,但是如果你需創(chuàng)建較多的等待線程時(shí),使用線程池的優(yōu)勢(shì)就越加明顯。見(jiàn)下例:

static AutoResetEvent ev=new AutoResetEvent(false);
public static int Main(string[] args)
{ ThreadPool.RegisterWaitForSingleObject(
  ev,
  new WaitOrTimerCallback(WaitThreadFunc),
  4,
  2000,
  false//表示每次完成等待操作后都重置計(jì)時(shí)器,直到注銷等待
  );
ThreadPool.QueueUserWorkItem (new WaitCallback (ThreadFunc),8);
Thread.Sleep (10000);
 return 0;
}
 public static void ThreadFunc(object b)
{ Console.WriteLine ("the object is {0}",b);
for(int i=0;i<2;i++)
{ Thread.Sleep (1000);
 ev.Set();
}
}
public static void WaitThreadFunc(object b,bool t)
{ Console.WriteLine ("the object is {0},t is {1}",b,t);
 }

其運(yùn)行結(jié)果為:

the object is 8
the object is 4,t is False
the object is 4,t is False
the object is 4,t is True
the object is 4,t is True
the object is 4,t is True

從以上結(jié)果我們可以看出線程ThreadFunc運(yùn)行了1次,而WaitThreadFunc運(yùn)行了5次。我們可以從WaitOrTimerCallback中的bool t參數(shù)判斷啟動(dòng)此線程的原因:t為false,則表示由于waitObject,否則則是由于超時(shí)。另外我們也可以通過(guò)object b向線程傳遞一些參數(shù)。

3、Timer

它適用于需周期性調(diào)用的方法,它不在創(chuàng)建計(jì)時(shí)器的線程中運(yùn)行,它在由系統(tǒng)自動(dòng)分配的單獨(dú)線程中運(yùn)行。這和Win32中的SetTimer方法類似。它的構(gòu)造為:

public Timer(
 TimerCallback callback,//所需調(diào)用的方法
 object state,//傳遞給callback的參數(shù)
 int dueTime,//多久后開(kāi)始調(diào)用callback
 int period//調(diào)用此方法的時(shí)間間隔
); 

// 如果 dueTime 為0,則 callback 立即執(zhí)行它的首次調(diào)用。如果 dueTime 為 Infinite,則 callback 不調(diào)用它的方法。計(jì)時(shí)器被禁用,但使用 Change 方法可以重新啟用它。如果 period 為0或 Infinite,并且 dueTime 不為 Infinite,則 callback 調(diào)用它的方法一次。計(jì)時(shí)器的定期行為被禁用,但使用 Change 方法可以重新啟用它。如果 period 為零 (0) 或 Infinite,并且 dueTime 不為 Infinite,則 callback 調(diào)用它的方法一次。計(jì)時(shí)器的定期行為被禁用,但使用 Change 方法可以重新啟用它。

在創(chuàng)建計(jì)時(shí)器之后若想改變它的period和dueTime,我們可以通過(guò)調(diào)用Timer的Change方法來(lái)改變:

public bool Change(
 int dueTime,
 int period
);//顯然所改變的兩個(gè)參數(shù)對(duì)應(yīng)于Timer中的兩參數(shù)
public static int Main(string[] args)
{ 
Console.WriteLine ("period is 1000");
Timer tm=new Timer (new TimerCallback (TimerCall),3,1000,1000);
Thread.Sleep (2000);
Console.WriteLine ("period is 500");
tm.Change (0,800);
Thread.Sleep (3000);
return 0;
 }
public static void TimerCall(object b)
{ 
Console.WriteLine ("timercallback; b is {0}",b);
}

其運(yùn)行結(jié)果為:

period is 1000
timercallback;b is 3
timercallback;b is 3
period is 500
timercallback;b is 3
timercallback;b is 3
timercallback;b is 3
timercallback;b is 3 

總結(jié)

從以上的簡(jiǎn)單介紹,我們可以看出它們各自使用的場(chǎng)合:Thread適用于那些需對(duì)線程進(jìn)行復(fù)雜控制的場(chǎng)合;ThreadPool適應(yīng)于一些需要多個(gè)線程而又較短任務(wù)(如一些常處于阻塞狀態(tài)的線程);Timer則適用于那些需周期性調(diào)用的方法。只要我們了解了它們的使用特點(diǎn),我們就可以很好的選擇合適的方法。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++中const的實(shí)現(xiàn)細(xì)節(jié)介紹(C,C#同理)

    C++中const的實(shí)現(xiàn)細(xì)節(jié)介紹(C,C#同理)

    本篇文章主要是對(duì)C++中const的實(shí)現(xiàn)細(xì)節(jié)進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-01-01
  • C#操作windows系統(tǒng)進(jìn)程的方法

    C#操作windows系統(tǒng)進(jìn)程的方法

    這篇文章介紹了C#操作windows系統(tǒng)進(jìn)程的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • C#中ref關(guān)鍵字的用法

    C#中ref關(guān)鍵字的用法

    這篇文章介紹了C#中ref關(guān)鍵字的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • 解析C#設(shè)計(jì)模式之單例模式

    解析C#設(shè)計(jì)模式之單例模式

    這篇文章主要介紹了C#設(shè)計(jì)模式之單例模式的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c# 設(shè)計(jì)模式的內(nèi)容,感興趣的朋友可以了解下
    2020-12-12
  • C#泛型類型知識(shí)講解

    C#泛型類型知識(shí)講解

    這篇文章主要介紹了C#泛型類型知識(shí),文中代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 如何使用C#中的Lazy的使用方法

    如何使用C#中的Lazy的使用方法

    這篇文章主要介紹了如何使用C#中的Lazy的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 分享我在工作中遇到的多線程下導(dǎo)致RCW無(wú)法釋放的問(wèn)題

    分享我在工作中遇到的多線程下導(dǎo)致RCW無(wú)法釋放的問(wèn)題

    最近在做項(xiàng)目中遇到一個(gè)問(wèn)題,在調(diào)用一個(gè)類庫(kù)中的方法時(shí),出現(xiàn)如下異常信息:嘗試釋放正在使用的RCW,活動(dòng)線程或其他線程上正在使用該 RCW,釋放正在使用的 RCW 的嘗試會(huì)導(dǎo)致?lián)p壞或數(shù)據(jù)丟失
    2015-12-12
  • C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐

    C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐

    有時(shí)我們可能會(huì)遇到需要的資料或教程被分成了幾部分存放在多個(gè)PDF文件中,本文主要介紹了C#實(shí)現(xiàn)PDF合并的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • C#實(shí)現(xiàn)俄羅斯方塊

    C#實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)俄羅斯方塊小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C#使用FluentHttpClient實(shí)現(xiàn)請(qǐng)求WebApi

    C#使用FluentHttpClient實(shí)現(xiàn)請(qǐng)求WebApi

    FluentHttpClient 是一個(gè)REST API 異步調(diào)用 HTTP 客戶端,調(diào)用過(guò)程非常便捷,下面我們就來(lái)學(xué)習(xí)一下C#如何使用FluentHttpClient實(shí)現(xiàn)請(qǐng)求WebApi吧
    2023-12-12

最新評(píng)論