如何解決C#lockthis問(wèn)題

本篇內(nèi)容介紹了“如何解決C# lock this問(wèn)題”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)專(zhuān)注于網(wǎng)站建設(shè),為客戶(hù)提供成都網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)開(kāi)發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類(lèi)網(wǎng)站都可以開(kāi)發(fā),高端網(wǎng)站設(shè)計(jì),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢(qián),價(jià)格優(yōu)惠,收費(fèi)合理。

在以前編程中遇到lock問(wèn)題總是使用lock(this)一鎖了之,出問(wèn)題后翻看MSDN突然發(fā)現(xiàn)下面幾行字:通常,應(yīng)避免鎖定 public 類(lèi)型,否則實(shí)例將超出代碼的控制范圍。常見(jiàn)的結(jié)構(gòu) lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 違反此準(zhǔn)則:如果實(shí)例可以被公共訪(fǎng)問(wèn),將出現(xiàn)C# lock this問(wèn)題。如果 MyType 可以被公共訪(fǎng)問(wèn),將出現(xiàn) lock (typeof (MyType)) 問(wèn)題。由于進(jìn)程中使用同一字符串的任何其他代碼將共享同一個(gè)鎖,所以出現(xiàn) lock(“myLock”) 問(wèn)題。來(lái)看看C# lock this問(wèn)題:如果有一個(gè)類(lèi)Class1,該類(lèi)有一個(gè)方法用lock(this)來(lái)實(shí)現(xiàn)互斥:

publicvoidMethod2()  {  lock(this)  {  System.Windows.Forms.MessageBox.Show("Method2End");  }  }

如果在同一個(gè)Class1的實(shí)例中,該Method2能夠互斥的執(zhí)行。但是如果是2個(gè)Class1的實(shí)例分別來(lái)執(zhí)行Method2,是沒(méi)有互斥效果的。因?yàn)檫@里的lock,只是對(duì)當(dāng)前的實(shí)例對(duì)象進(jìn)行了加鎖。

Lock(typeof(MyType))鎖定住的對(duì)象范圍更為廣泛,由于一個(gè)類(lèi)的所有實(shí)例都只有一個(gè)類(lèi)型對(duì)象(該對(duì)象是typeof的返回結(jié)果),鎖定它,就鎖定了該對(duì)象的所有實(shí)例,微軟現(xiàn)在建議,不要使用lock(typeof(MyType)),因?yàn)殒i定類(lèi)型對(duì)象是個(gè)很緩慢的過(guò)程,并且類(lèi)中的其他線(xiàn)程、甚至在同一個(gè)應(yīng)用程序域中運(yùn)行的其他程序都可以訪(fǎng)問(wèn)該類(lèi)型對(duì)象,因此,它們就有可能代替您鎖定類(lèi)型對(duì)象,完全阻止您的執(zhí)行,從而導(dǎo)致你自己的代碼的掛起。

鎖住一個(gè)字符串更為神奇,只要字符串內(nèi)容相同,就能引起程序掛起。原因是在.NET中,字符串會(huì)被暫時(shí)存放,如果兩個(gè)變量的字符串內(nèi)容相同的話(huà),.NET會(huì)把暫存的字符串對(duì)象分配給該變量。所以如果有兩個(gè)地方都在使用lock(“my lock”)的話(huà),它們實(shí)際鎖住的是同一個(gè)對(duì)象。到此,微軟給出了個(gè)lock的建議用法:鎖定一個(gè)私有的static 成員變量。

.NET在一些集合類(lèi)中(比如ArrayList,HashTable,Queue,Stack)已經(jīng)提供了一個(gè)供lock使用的對(duì)象SyncRoot,用Reflector工具查看了SyncRoot屬性的代碼,在Array中,該屬性只有一句話(huà):return this,這樣和lock array的當(dāng)前實(shí)例是一樣的。ArrayList中的SyncRoot有所不同

get  {  if(this._syncRoot==null)  {  Interlocked.CompareExchange(refthis._syncRoot,newobject(),null);  }  returnthis._syncRoot;

其中Interlocked類(lèi)是專(zhuān)門(mén)為多個(gè)線(xiàn)程共享的變量提供原子操作(如果你想鎖定的對(duì)象是基本數(shù)據(jù)類(lèi)型,那么請(qǐng)使用這個(gè)類(lèi)),CompareExchange方法將當(dāng)前syncRoot和null做比較,如果相等,就替換成new object(),這樣做是為了保證多個(gè)線(xiàn)程在使用syncRoot時(shí)是線(xiàn)程安全的。集合類(lèi)中還有一個(gè)方法是和同步相關(guān)的:Synchronized,該方法返回一個(gè)對(duì)應(yīng)的集合類(lèi)的wrapper類(lèi),該類(lèi)是線(xiàn)程安全的,因?yàn)樗拇蟛糠址椒ǘ加胠ock來(lái)進(jìn)行了同步處理,比如Add方法:

publicoverridevoidAdd(objectkey,objectvalue)  {  lock(this._table.SyncRoot)  {  this._table.Add(key,value);  }  }

這里要特別注意的是MSDN提到:從頭到尾對(duì)一個(gè)集合進(jìn)行枚舉本質(zhì)上并不是一個(gè)線(xiàn)程安全的過(guò)程。即使一個(gè)集合已進(jìn)行同步,其他線(xiàn)程仍可以修改該集合,這將導(dǎo)致枚舉數(shù)引發(fā)異常。若要在枚舉過(guò)程中保證線(xiàn)程安全,可以在整個(gè)枚舉過(guò)程中鎖定集合:

QueuemyCollection=newQueue();  lock(myCollection.SyncRoot){  foreach(ObjectiteminmyCollection){  //Insertyourcodehere.  }  }

“如何解決C# lock this問(wèn)題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)站名稱(chēng):如何解決C#lockthis問(wèn)題
文章出自:http://bm7419.com/article18/iidogp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)自適應(yīng)網(wǎng)站、搜索引擎優(yōu)化、網(wǎng)頁(yè)設(shè)計(jì)公司做網(wǎng)站、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷(xiāo)型網(wǎng)站建設(shè)