C#使用隊(duì)列(Queue)解決簡(jiǎn)單的并發(fā)問題
本文通過實(shí)例,更具體的講解了隊(duì)列,隊(duì)列(Queue)代表了一個(gè)先進(jìn)先出的對(duì)象集合。當(dāng)您需要對(duì)各項(xiàng)進(jìn)行先進(jìn)先出的訪問時(shí),則使用隊(duì)列。當(dāng)您在列表中添加一項(xiàng),稱為入隊(duì),當(dāng)您從列表中移除一項(xiàng)時(shí),稱為出隊(duì)。
有一個(gè)場(chǎng)景:一個(gè)搶購(gòu)的項(xiàng)目,假設(shè)有5件商品,誰先搶到誰可以買,但是如果此時(shí)此刻(這里的此時(shí)此刻假設(shè)是相同的時(shí)間),有100人去搶這個(gè)商品,如果使用平時(shí)的方法會(huì)出現(xiàn)什么情況呢?你懂的,這里所說是就是有關(guān)并發(fā)的問題。
平時(shí)我們?nèi)コ匈?gòu)物去結(jié)賬的時(shí)候就是排隊(duì),這里我們先讓搶購(gòu)人排好隊(duì),按時(shí)間,誰先點(diǎn)擊的搶購(gòu)按鈕誰就排在前面,這樣就形成了一個(gè)隊(duì)列,然后我們?cè)賹?duì)這個(gè)隊(duì)列處理,這樣就不會(huì)出現(xiàn)并發(fā)的問題了。(至少可以處理這樣簡(jiǎn)單的并發(fā),這里不討論太復(fù)雜的并發(fā))
案例:
要求:有一個(gè)發(fā)布文章的接口,每發(fā)布一篇文章,調(diào)用一下接口。(這里不用批量發(fā)布,為了講解這個(gè))
建立一個(gè)這樣的處理程序類,BusinessInfoHelper.cs
namespace MyNameSpace
{
//隊(duì)列臨時(shí)類
public class QueueInfo
{
public string medias { get; set; }
public string proids { get; set; }
public string host { get; set; }
public string userid { get; set; }
public string feedid { get; set; }
}
public class BusinessInfoHelper
{
#region 解決發(fā)布時(shí)含有優(yōu)質(zhì)媒體時(shí),前臺(tái)頁面卡住的現(xiàn)象
//原理:利用生產(chǎn)者消費(fèi)者模式進(jìn)行入列出列操作
public readonly static BusinessInfoHelper Instance = new BusinessInfoHelper();
private BusinessInfoHelper()
{ }
private Queue<QueueInfo> ListQueue = new Queue<QueueInfo>();
public void AddQueue(string medias, string proids, string host, string userid, string feedid) //入列
{
QueueInfo queueinfo = new QueueInfo();
queueinfo.medias = medias;
queueinfo.proids = proids;
queueinfo.host = host;
queueinfo.userid = userid;
queueinfo.feedid = feedid;
ListQueue.Enqueue(queueinfo);
}
public void Start()//啟動(dòng)
{
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
private void threadStart()
{
while (true)
{
if (ListQueue.Count > 0)
{
try
{
ScanQueue();
}
catch (Exception ex)
{
LO_LogInfo.WLlog(ex.ToString());
}
}
else
{
//沒有任務(wù),休息3秒鐘
Thread.Sleep(3000);
}
}
}
//要執(zhí)行的方法
private void ScanQueue()
{
while (ListQueue.Count > 0)
{
try
{
//從隊(duì)列中取出
QueueInfo queueinfo = ListQueue.Dequeue();
//取出的queueinfo就可以用了,里面有你要的東西
//以下就是處理程序了
//。。。。。。
}
catch (Exception ex)
{
throw;
}
}
}
#endregion
}
}
以上頁面寫好后,在程序開始運(yùn)行時(shí)就得啟動(dòng)這個(gè)線程去不停的處理任務(wù),那么我們?cè)贕lobal的Application_Start里可以這樣寫:
//啟動(dòng)發(fā)布優(yōu)質(zhì)媒體程序? MyNameSpace.BusinessInfoHelper.Instance.Start();?
有一個(gè)問題出來了,如果我處理完隊(duì)列中的一條記錄后,想返回這條記錄的ID,這個(gè)程序好像不能完成,我就使用了另一個(gè)方法 Lock方法 ,把方法鎖定,具體的如下,
在頁面中定義全局的鎖:
private static object lockObject= new Object();?
在方法中這樣調(diào)用:
lock(lockObject)?
?
{?
?
//........?
?
}?以上是本文的全部?jī)?nèi)容,希望對(duì)大家進(jìn)一步學(xué)習(xí)隊(duì)列有所幫助
相關(guān)文章
C# CancellationToken和CancellationTokenSource的用法詳解
做了.net core之后,發(fā)現(xiàn)CancellationToken用的越來越平凡了。這也難怪,原來.net framework使用異步的不是很多,而.net core首推異步編程,到處可以看到Task的影子,而CancellationToken正好是異步Task的一個(gè)控制器,所以花點(diǎn)時(shí)間做個(gè)筆記2021-06-06
winform中寫app.config文件時(shí)調(diào)試情況下沒有改變的原因
讀取很簡(jiǎn)單基本都用過 ConfigurationManager.AppSettings[""].ToString() 寫config不是很常用2013-02-02
Unity2021發(fā)布WebGL與網(wǎng)頁交互問題的解決
本文主要介紹了Unity2021發(fā)布WebGL與網(wǎng)頁交互問題的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05
C#實(shí)現(xiàn)圖形位置組合轉(zhuǎn)換的方法
這篇文章主要介紹了C#實(shí)現(xiàn)圖形位置組合轉(zhuǎn)換的方法,涉及C#使用Matrix操作圖形的相關(guān)技巧,需要的朋友可以參考下2015-06-06
C# wpf簡(jiǎn)單顏色板的實(shí)現(xiàn)
wpf本身沒有提供顏色板之類的控件,有些業(yè)務(wù)使用場(chǎng)景需要使用顏色板之類的控件,本文就簡(jiǎn)單實(shí)現(xiàn),感興趣的可以了解一下2021-10-10

