亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入分析C#中的異步和多線(xiàn)程

 更新時(shí)間:2021年01月16日 09:33:24   作者:碼農(nóng)譯站  
這篇文章主要介紹了C#中異步和多線(xiàn)程的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下

許多開(kāi)發(fā)人員對(duì)異步代碼和多線(xiàn)程以及它們的工作原理和使用方法都有錯(cuò)誤的認(rèn)識(shí)。在這里,你將了解這兩個(gè)概念之間的區(qū)別,并使用c#實(shí)現(xiàn)它們。

我:“服務(wù)員,這是我第一次來(lái)這家餐廳。通常需要4個(gè)小時(shí)才能拿到食物嗎?”

服務(wù)員:“哦,是的,先生。這家餐廳的廚房里只有一個(gè)廚師。”

我:“……只有一個(gè)廚師嗎?”

服務(wù)員:“是的,先生,我們有好幾個(gè)廚師,但每次只有一個(gè)在廚房工作?!?/p>

我:“所以其他10個(gè)穿著廚師服站在廚房里的人……什么都不做嗎?廚房太小了嗎?”

服務(wù)員:“哦,我們的廚房很大,先生?!?/p>

我:“那為什么他們不同時(shí)工作呢?”

服務(wù)員:“先生,這倒是個(gè)好主意,但我們還沒(méi)想好怎么做?!?/p>

我:“好了,奇怪。但是…嘿…現(xiàn)在的主廚在哪里?我現(xiàn)在沒(méi)看見(jiàn)有人在廚房里?!?/p>

服務(wù)員:“是的,先生。有一份訂單的廚房用品已經(jīng)用完了,所以廚師已經(jīng)停止烹飪,站在外面等著送貨了?!?/p>

我:“看起來(lái)他可以一邊等一邊做飯,也許送貨員可以直接告訴他們什么時(shí)候到了?”

服務(wù)員:“又是一個(gè)絕妙的主意,先生。我們?cè)诤竺嬗兴拓涢T(mén)鈴,但廚師喜歡等。我去給你再拿點(diǎn)水來(lái)?!?/p>

多糟糕的餐廳,對(duì)吧?不幸的是,很多程序都是這樣工作的。

有兩種不同的方法可以讓這家餐廳做得更好。

首先,很明顯,每個(gè)單獨(dú)的晚餐訂單可以由不同的廚師來(lái)處理。每一種都是一個(gè)必須按特定順序發(fā)生的事情列表(準(zhǔn)備原料,然后混合它們,然后烹飪,等等)。因此,如果每個(gè)廚師都致力于處理這一清單上的東西,幾份晚餐訂單可以同時(shí)做出。

這是一個(gè)真實(shí)世界中的多線(xiàn)程示例。計(jì)算機(jī)有能力讓多個(gè)不同的線(xiàn)程同時(shí)運(yùn)行,每個(gè)線(xiàn)程負(fù)責(zé)按特定順序執(zhí)行一系列活動(dòng)。

然后還有異步行為。需要明確的是,異步不是多線(xiàn)程的。還記得那個(gè)一直在等外賣(mài)的廚師嗎?真是浪費(fèi)時(shí)間!在等待的過(guò)程中,他沒(méi)有做任何有意義的事情,比如做飯。而且,等待也不會(huì)讓送貨更快。一旦他打電話(huà)訂購(gòu)供應(yīng)品,發(fā)貨就會(huì)隨時(shí)發(fā)生,所以為什么要等呢?相反,送貨員只需按門(mén)鈴,說(shuō)一句:“嘿,這是你的供應(yīng)品!”

有很多I/O活動(dòng)是由代碼之外的東西處理的。例如,向遠(yuǎn)程服務(wù)器發(fā)送一個(gè)網(wǎng)絡(luò)請(qǐng)求。這就像給餐廳點(diǎn)餐一樣。你的代碼所做的唯一事情就是進(jìn)行調(diào)用并接收結(jié)果。如果選擇等待結(jié)果,在這兩者之間完全不做任何事情,那么這就是“同步”行為。

然而,如果你更喜歡在結(jié)果返回時(shí)被打斷/通知(就像送貨員到達(dá)時(shí)按門(mén)鈴),同時(shí)可以處理其他事情,那么這就是“異步”行為。

只要工作是由不受當(dāng)前代碼直接控制的對(duì)象完成的,就可以使用異步代碼。例如,當(dāng)你向硬盤(pán)驅(qū)動(dòng)器寫(xiě)入一堆數(shù)據(jù)時(shí),你的代碼并沒(méi)有執(zhí)行實(shí)際的寫(xiě)入操作。它只是請(qǐng)求硬件執(zhí)行該任務(wù)。因此,你可以使用異步編碼開(kāi)始編寫(xiě),然后在編寫(xiě)完成時(shí)得到通知,同時(shí)繼續(xù)處理其他事情。

異步的優(yōu)點(diǎn)在于不需要額外的線(xiàn)程,因此非常高效。

“等等!”你說(shuō)?!叭绻麤](méi)有額外的線(xiàn)程,那么誰(shuí)或什么在等待結(jié)果?代碼如何知道返回的結(jié)果?”

還記得那個(gè)門(mén)鈴嗎?你的電腦里有一個(gè)系統(tǒng)叫做“中斷”系統(tǒng),它的工作原理有點(diǎn)像那個(gè)門(mén)鈴。當(dāng)你的代碼開(kāi)始一個(gè)異步活動(dòng)時(shí),它基本上會(huì)安裝一個(gè)虛擬的門(mén)鈴。當(dāng)其他任務(wù)(寫(xiě)入硬盤(pán)驅(qū)動(dòng)器,等待網(wǎng)絡(luò)響應(yīng)等)完成時(shí),中斷系統(tǒng)“中斷”當(dāng)前運(yùn)行的代碼并按下門(mén)鈴,讓你的應(yīng)用程序知道有一個(gè)任務(wù)在等待!不需要線(xiàn)程坐在那里等待!

讓我們快速回顧一下我們的兩種工具:

多線(xiàn)程:使用一個(gè)額外的線(xiàn)程來(lái)執(zhí)行一系列活動(dòng)/任務(wù)。

異步:使用同一個(gè)線(xiàn)程和中斷系統(tǒng),讓線(xiàn)程外的其他組件完成一些活動(dòng),并在活動(dòng)結(jié)束時(shí)得到通知。

UI線(xiàn)程

還有一件重要的事情需要知道的是為什么使用這些工具是好的。在.net中,有一個(gè)主線(xiàn)程叫做UI線(xiàn)程,它負(fù)責(zé)更新屏幕的所有可視部分。默認(rèn)情況下,這是一切運(yùn)行的地方。當(dāng)你點(diǎn)擊一個(gè)按鈕,你想看到按鈕被短暫地按下,然后返回,這是UI線(xiàn)程的責(zé)任。你的應(yīng)用中只有一個(gè)UI線(xiàn)程,這意味著如果你的UI線(xiàn)程忙著做繁重的計(jì)算或等待網(wǎng)絡(luò)請(qǐng)求之類(lèi)的事情,那么它不能更新你在屏幕上看到的東西,直到它完成。結(jié)果是,你的應(yīng)用程序看起來(lái)像“凍結(jié)”——你可以點(diǎn)擊一個(gè)按鈕,但似乎什么都不會(huì)發(fā)生,因?yàn)閁I線(xiàn)程正在忙著做其他事情。

理想情況下,你希望UI線(xiàn)程盡可能地空閑,這樣你的應(yīng)用程序似乎總是在響應(yīng)用戶(hù)的操作。這就是異步和多線(xiàn)程的由來(lái)。通過(guò)使用這些工具,可以確保在其他地方完成繁重的工作,UI線(xiàn)程保持良好和響應(yīng)性。

現(xiàn)在讓我們看看如何在c#中使用這些工具。

C#的異步操作

執(zhí)行異步操作的代碼非常簡(jiǎn)單。你應(yīng)該知道兩個(gè)主要的關(guān)鍵字:“async”和“await”,所以人們通常將其稱(chēng)為async/await。假設(shè)你現(xiàn)在有這樣的代碼:

public void Loopy()
{
  var hugeFiles = new string[] {
   "Gr8Gonzos_Home_Movie_In_8k_Res.mkv", // 1 GB
   "War_And_Peace_In_150_Languages.rtf", // 1.2 GB
   "Cats_On_Catnip.mpg"         // 0.9 GB
  };

  foreach (var hugeFile in hugeFiles)
  {
    ReadAHugeFile(hugeFile);
  }
  
  MessageBox.Show("All done!");
}


public byte[] ReadAHugeFile(string bigFile)
{
  var fileSize = new FileInfo(bigFile).Length; // Get the file size
  var allData = new byte[fileSize];      // Allocate a byte array as large as our file
  using (var fs = new System.IO.FileStream(bigFile, FileMode.Open))
  {
    fs.Read(allData, 0, (int)fileSize);   // Read the entire file...
  }
  return allData;               // ...and return those bytes!
}

在當(dāng)前的形式中,這些都是同步運(yùn)行的。如果你點(diǎn)擊一個(gè)按鈕從UI線(xiàn)程運(yùn)行Loopy(),那么應(yīng)用程序?qū)⑺坪鮾鼋Y(jié),直到所有三大文件閱讀,因?yàn)槊總€(gè)“ReadAHugeFile”是要花很長(zhǎng)時(shí)間在UI線(xiàn)程上運(yùn)行,并將同步閱讀。這可不好!讓我們看看能否將ReadAHugeFile變?yōu)楫惒降倪@樣UI線(xiàn)程就能繼續(xù)處理其他東西。

無(wú)論何時(shí),只要有支持異步的命令,微軟通常會(huì)給我們同步和異步版本的這些命令。在上面的代碼中,System.IO.FileStream對(duì)象同時(shí)具有"Read"和"ReadAsync"方法。所以第一步就是將“fs.Read”修改成“fs.ReadAsync”。

public byte[] ReadAHugeFile(string bigFile)
{
  var fileSize = new FileInfo(bigFile).Length; // Get the file size
  var allData = new byte[fileSize];      // Allocate a byte array as large as our file
  using (var fs = new System.IO.FileStream(bigFile, FileMode.Open))
  {
    fs.ReadAsync(allData, 0, (int)fileSize); // Read the entire file asynchronously...
  }
  return allData;               // ...and return those bytes!
}

如果現(xiàn)在運(yùn)行它,它會(huì)立即返回,并且“allData”字節(jié)數(shù)組中不會(huì)有任何數(shù)據(jù)。為什么?

這是因?yàn)镽eadAsync是開(kāi)始讀取并返回一個(gè)任務(wù)對(duì)象,這有點(diǎn)像一個(gè)書(shū)簽。這是.net的一個(gè)“Promise”,一旦異步活動(dòng)完成(例如從硬盤(pán)讀取數(shù)據(jù)),它將返回結(jié)果,任務(wù)對(duì)象可以用來(lái)訪(fǎng)問(wèn)結(jié)果。但如果我們對(duì)這個(gè)任務(wù)不做任何事情,那么系統(tǒng)就會(huì)立即繼續(xù)到下一行代碼,也就是我們的"return allData"行,它會(huì)返回一個(gè)尚未填滿(mǎn)數(shù)據(jù)的數(shù)組。

因此,告訴代碼等待結(jié)果是很有用的(但這樣一來(lái),原始線(xiàn)程可以在此期間繼續(xù)做其他事情)。為了做到這一點(diǎn),我們使用了一個(gè)"awaiter",它就像在async調(diào)用之前添加單詞"await"一樣簡(jiǎn)單:

public byte[] ReadAHugeFile(string bigFile)
{
  var fileSize = new FileInfo(bigFile).Length; // Get the file size
  var allData = new byte[fileSize];      // Allocate a byte array as large as our file
  using (var fs = new System.IO.FileStream(bigFile, FileMode.Open))
  {
    await fs.ReadAsync(allData, 0, (int)fileSize); // Read the entire file asynchronously...
  }
  return allData;               // ...and return those bytes!
}

如果現(xiàn)在運(yùn)行它,它會(huì)立即返回,并且“allData”字節(jié)數(shù)組中不會(huì)有任何數(shù)據(jù)。為什么?

這是因?yàn)镽eadAsync是開(kāi)始讀取并返回一個(gè)任務(wù)對(duì)象,這有點(diǎn)像一個(gè)書(shū)簽。這是.net的一個(gè)“Promise”,一旦異步活動(dòng)完成(例如從硬盤(pán)讀取數(shù)據(jù)),它將返回結(jié)果,任務(wù)對(duì)象可以用來(lái)訪(fǎng)問(wèn)結(jié)果。但如果我們對(duì)這個(gè)任務(wù)不做任何事情,那么系統(tǒng)就會(huì)立即繼續(xù)到下一行代碼,也就是我們的"return allData"行,它會(huì)返回一個(gè)尚未填滿(mǎn)數(shù)據(jù)的數(shù)組。

因此,告訴代碼等待結(jié)果是很有用的(但這樣一來(lái),原始線(xiàn)程可以在此期間繼續(xù)做其他事情)。為了做到這一點(diǎn),我們使用了一個(gè)"awaiter",它就像在async調(diào)用之前添加單詞"await"一樣簡(jiǎn)單:

public byte[] ReadAHugeFile(string bigFile)
{
  var fileSize = new FileInfo(bigFile).Length; // Get the file size
  var allData = new byte[fileSize];      // Allocate a byte array as large as our file
  using (var fs = new System.IO.FileStream(bigFile, FileMode.Open))
  {
    await fs.ReadAsync(allData, 0, (int)fileSize); // Read the entire file asynchronously...
  }
  return allData;               // ...and return those bytes!
}

哦。如果你試過(guò),你會(huì)發(fā)現(xiàn)有一個(gè)錯(cuò)誤。這是因?yàn)?net需要知道這個(gè)方法是異步的,它最終會(huì)返回一個(gè)字節(jié)數(shù)組。因此,我們做的第一件事是在返回類(lèi)型之前添加單詞“async”,然后用Task<…>,是這樣的:

public async Task<byte[]> ReadAHugeFile(string bigFile)
{
  var fileSize = new FileInfo(bigFile).Length; // Get the file size
  var allData = new byte[fileSize];      // Allocate a byte array as large as our file
  using (var fs = new System.IO.FileStream(bigFile, FileMode.Open))
  {
    await fs.ReadAsync(allData, 0, (int)fileSize); // Read the entire file asynchronously...
  }
  return allData;               // ...and return those bytes!
}

好吧!現(xiàn)在我們烹飪!如果我們現(xiàn)在運(yùn)行我們的代碼,它將繼續(xù)在UI線(xiàn)程上運(yùn)行,直到我們到達(dá)ReadAsync方法的await。此時(shí),. net知道這是一個(gè)將由硬盤(pán)執(zhí)行的活動(dòng),因此“await”將一個(gè)小書(shū)簽放在當(dāng)前位置,然后UI線(xiàn)程返回到它的正常處理(所有的視覺(jué)更新等)。

隨后,一旦硬盤(pán)驅(qū)動(dòng)器讀取了所有數(shù)據(jù),ReadAsync方法將其全部復(fù)制到allData字節(jié)數(shù)組中,任務(wù)現(xiàn)在就完成了,因此系統(tǒng)按門(mén)鈴,讓原始線(xiàn)程知道結(jié)果已經(jīng)準(zhǔn)備好了。原始線(xiàn)程說(shuō):“太棒了!讓我回到離開(kāi)的地方!”一有機(jī)會(huì),它就會(huì)回到“await fs.ReadSync”,然后繼續(xù)下一步,返回allData數(shù)組,這個(gè)數(shù)組現(xiàn)在已經(jīng)填充了我們的數(shù)據(jù)。

如果你在一個(gè)接一個(gè)地看一個(gè)例子,并且使用的是最近的Visual Studio版本,你會(huì)注意到這一行:

ReadAHugeFile(hugeFile);

…現(xiàn)在,它用綠色下劃線(xiàn)表示,如果將鼠標(biāo)懸停在它上面,它會(huì)說(shuō),“因?yàn)檫@個(gè)調(diào)用沒(méi)有被等待,所以在調(diào)用完成之前,當(dāng)前方法的執(zhí)行將繼續(xù)?!笨紤]對(duì)調(diào)用的結(jié)果應(yīng)用'await'操作符。"

這是Visual Studio讓你知道它承認(rèn)ReadAHugeFile()是一個(gè)異步的方法,而不是返回一個(gè)結(jié)果,這也是返回任務(wù),所以如果你想等待結(jié)果,然后你就可以添加一個(gè)“await”:

await ReadAHugeFile(hugeFile);

…但如果我們這樣做了,那么你還必須更新方法簽名:

public async void Loopy()

注意,如果我們?cè)谝粋€(gè)不返回任何東西的方法上(void返回類(lèi)型),那么我們不需要將返回類(lèi)型包裝在Task<…>中。

但是,我們不要這樣做。相反,讓我們來(lái)了解一下我們可以用異步做些什么。

如果你不想等待ReadAHugeFile(hugeFile)的結(jié)果,因?yàn)槟憧赡懿魂P(guān)心最終的結(jié)果,但你不喜歡綠色下劃線(xiàn)/警告,你可以使用一個(gè)特殊的技巧來(lái)告訴.net。只需將結(jié)果賦給_字符,就像這樣:

_ = ReadAHugeFile(hugeFile);

這就是.net的語(yǔ)法,表示“我不在乎結(jié)果,但我不希望用它的警告來(lái)打擾我?!?/p>

好吧,我們?cè)囋噭e的。如果我們?cè)谶@一行上使用了await,那么它將等待第一個(gè)文件被異步讀取,然后等待第二個(gè)文件被異步讀取,最后等待第三個(gè)文件被異步讀取。但是…如果我們想要同時(shí)異步地讀取所有3個(gè)文件,然后在所有3個(gè)文件都完成之后,我們?cè)试S代碼繼續(xù)到下一行,該怎么辦?

有一個(gè)叫做Task.WhenAll()的方法,它本身是一個(gè)你可以await的異步方法。傳入其他任務(wù)對(duì)象的列表,然后等待它,一旦所有任務(wù)都完成,它就會(huì)完成。所以最簡(jiǎn)單的方法就是創(chuàng)建一個(gè)List<Task>對(duì)象:

List<Task> readingTasks = new List<Task>();

…然后,當(dāng)我們將每個(gè)ReadAHugeFile()調(diào)用中的Task添加到列表中時(shí):

foreach (var hugeFile in hugeFiles) {  
   readingTasks.Add(ReadAHugeFile(hugeFile));
}

…最后我們 await Task.WhenAll():

await Task.WhenAll(readingTasks);

最終的方法是這樣的:

public async void Loopy()
{
  var hugeFiles = new string[] {
   "Gr8Gonzos_Home_Movie_In_8k_Res.mkv", // 1 GB
   "War_And_Peace_In_150_Languages.rtf", // 1.2 GB
   "Cats_On_Catnip.mpg"         // 0.9 GB
  };


  List<Task> readingTasks = new List<Task>();
  foreach (var hugeFile in hugeFiles)
  {
    readingTasks.Add(ReadAHugeFile(hugeFile));
  }
  await Task.WhenAll(readingTasks);


  MessageBox.Show(sb.ToString());
}

當(dāng)涉及到并行活動(dòng)時(shí),一些I/O機(jī)制比其他機(jī)制工作得更好(例如,網(wǎng)絡(luò)請(qǐng)求通常比硬盤(pán)讀取工作得更好,但這取決于硬件),但原理是相同的。

現(xiàn)在,“await”操作符還要做的最后一件事是提取最終結(jié)果。所以在上面的例子中,ReadAHugeFile返回一個(gè)任務(wù)<byte[]>。await的神奇功能會(huì)在完成后自動(dòng)拋出Task<>包裝器,并返回byte[]數(shù)組,所以如果你想訪(fǎng)問(wèn)Loopy()中的字節(jié),你可以這樣做:

byte[] data = await ReadAHugeFile(hugeFile);

再次強(qiáng)調(diào),await是一個(gè)神奇的小命令,它使異步編程變得非常簡(jiǎn)單,并為你處理各種各樣的小事情。

現(xiàn)在讓我們轉(zhuǎn)向多線(xiàn)程。

C#中的多線(xiàn)程

微軟有時(shí)會(huì)給你10種不同的方法來(lái)做同樣的事情,這就是它如何使用多線(xiàn)程。你有BackgroundWorker類(lèi)、Thread和Task(它們有幾個(gè)變體)。最終,它們都做著相同的事情,只是有不同的功能?,F(xiàn)在,大多數(shù)人都使用Task,因?yàn)樗鼈兊脑O(shè)置和使用都很簡(jiǎn)單,而且如果你想這樣做的話(huà)(我們稍后會(huì)講到),它們也可以很好地與異步代碼交互。如果你好奇的話(huà),關(guān)于這些具體區(qū)別有很多文章,但是我們?cè)谶@里使用任務(wù)。

要讓任何方法在單獨(dú)的線(xiàn)程中運(yùn)行,只需使用Task.Run()方法來(lái)執(zhí)行它。例如,假設(shè)你有這樣一個(gè)方法:

public void DoRandomCalculations(int howMany)
{
  var rng = new Random();
  for (int i = 0; i < howMany; i++)
  {
    int a = rng.Next(1, 1000);
    int b = rng.Next(1, 1000);
    int sum = 0;
    sum = a + b;
  }
}

我們可以像這樣在當(dāng)前線(xiàn)程中調(diào)用它:

DoRandomCalculations(1000000); 

或者我們可以讓另一個(gè)線(xiàn)程來(lái)做這個(gè)工作:

Task.Run(() => DoRandomCalculations(1000000)); 

當(dāng)然,有一些不同的版本,但這是總體思路。

Task. run()的一個(gè)優(yōu)點(diǎn)是它返回一個(gè)我們可以等待的任務(wù)對(duì)象。因此,如果想在一個(gè)單獨(dú)的線(xiàn)程中運(yùn)行一堆代碼,然后在進(jìn)入下一步之前等待它完成,你可以使用await,就像你在前面一節(jié)看到的那樣:

var finalData = await Task.Run(() => {});

請(qǐng)記住,本文討論的是如何開(kāi)始,以及這些概念是如何工作的,但它并不是全面的。但是也許有了這些知識(shí),你將能夠理解其他人關(guān)于多線(xiàn)程和異步編碼更高級(jí)種類(lèi)的更復(fù)雜的文章。

以上就是深入分析C#中的異步和多線(xiàn)程的詳細(xì)內(nèi)容,更多關(guān)于C#中的異步和多線(xiàn)程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#實(shí)現(xiàn)獲取電腦硬件顯卡信息的示例代碼

    C#實(shí)現(xiàn)獲取電腦硬件顯卡信息的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用C#實(shí)現(xiàn)獲取電腦硬件顯卡信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • C#交錯(cuò)數(shù)組淺析

    C#交錯(cuò)數(shù)組淺析

    這里介紹C#交錯(cuò)數(shù)組,數(shù)組是具有同一類(lèi)型的一組值,數(shù)組是引用類(lèi)型的,因此存在內(nèi)存堆中。數(shù)組中的元素值可以在定義數(shù)組時(shí)賦予,也可以在定義數(shù)組后對(duì)單個(gè)元素進(jìn)行賦值
    2012-09-09
  • C#計(jì)算兩個(gè)時(shí)間差的方法代碼分享

    C#計(jì)算兩個(gè)時(shí)間差的方法代碼分享

    做項(xiàng)目需要用到計(jì)算時(shí)間差,就整理出來(lái)供有需要的朋友參考一下
    2013-12-12
  • Unity3D游戲開(kāi)發(fā)數(shù)據(jù)持久化PlayerPrefs的用法詳解

    Unity3D游戲開(kāi)發(fā)數(shù)據(jù)持久化PlayerPrefs的用法詳解

    在本篇文章里小編給大家整理了關(guān)于Unity3D游戲開(kāi)發(fā)之?dāng)?shù)據(jù)持久化PlayerPrefs的使用的相關(guān)知識(shí)點(diǎn)內(nèi)容,需要的朋友們參考下。
    2019-08-08
  • 詳解C#中委托的概念與使用

    詳解C#中委托的概念與使用

    委托這個(gè)名字取的神乎其神的,但實(shí)質(zhì)是函數(shù)式編程,把函數(shù)作為參數(shù)傳遞給另一個(gè)參數(shù)。這篇文章主要為大家介紹一下C#中委托的概念與使用,需要的可以參考一下
    2023-02-02
  • Unity 實(shí)現(xiàn)貼花效果的制作教程

    Unity 實(shí)現(xiàn)貼花效果的制作教程

    有些游戲中的戰(zhàn)斗痕跡的效果會(huì)通過(guò)貼花來(lái)實(shí)現(xiàn)的,貼花的方式多種多樣。而在Unity中,有一種給官方文檔提供代碼的解決方案。本文將這些代碼的基礎(chǔ)上做一個(gè)繪圖的貼花效果,感興趣的童鞋可以參考一下
    2021-11-11
  • 在C#中捕獲內(nèi)存不足異常

    在C#中捕獲內(nèi)存不足異常

    這篇文章主要介紹了在C#中捕獲內(nèi)存不足異常,下面文章內(nèi)容圍繞如何在C#中捕獲內(nèi)存不足異常的相關(guān)資料展開(kāi)詳細(xì)內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你有所幫助
    2021-12-12
  • c#的treeview綁定和獲取值的方法

    c#的treeview綁定和獲取值的方法

    這篇文章主要介紹了c#的treeview綁定和獲取值的方法,需要的朋友可以參考下
    2014-04-04
  • Unity 使用TexturePacker打包圖集的操作方法

    Unity 使用TexturePacker打包圖集的操作方法

    這篇文章主要介紹了Unity 使用TexturePacker打包圖集的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • C#生成指定范圍內(nèi)的不重復(fù)隨機(jī)數(shù)

    C#生成指定范圍內(nèi)的不重復(fù)隨機(jī)數(shù)

    對(duì)于隨機(jī)數(shù),大家都知道,計(jì)算機(jī)不 可能產(chǎn)生完全隨機(jī)的數(shù)字,所謂的隨機(jī)數(shù)發(fā)生器都是通過(guò)一定的算法對(duì)事先選定的隨機(jī)種子做復(fù)雜的運(yùn)算,用產(chǎn)生的結(jié)果來(lái)近似的模擬完全隨機(jī)數(shù),這種隨機(jī)數(shù)被稱(chēng) 作偽隨機(jī)數(shù)。偽隨機(jī)數(shù)是以相同的概率從一組有限的數(shù)字中選取的。
    2015-05-05

最新評(píng)論