﻿
{"id":11408,"date":"2019-08-07T14:11:47","date_gmt":"2019-08-07T14:11:47","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=11408"},"modified":"2019-08-07T14:11:47","modified_gmt":"2019-08-07T14:11:47","slug":"thread-safe-concurrentqueue-concurrentdictionary-concurrentbag-concurrentstack-ve-blockingcollection-koleksiyonlari-ve-kullanim-durumlari","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/thread-safe-concurrentqueue-concurrentdictionary-concurrentbag-concurrentstack-ve-blockingcollection-koleksiyonlari-ve-kullanim-durumlari\/","title":{"rendered":"Thread Safe &#8211; ConcurrentQueue, ConcurrentDictionary, ConcurrentBag, ConcurrentStack ve BlockingCollection Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Yaz\u0131l\u0131msal problemlere \u00e7\u00f6z\u00fcm olarak geli\u015ftirdi\u011fimiz algoritmalar ihtiyaca d\u00f6n\u00fck olarak yer yer asenkron i\u015flevde geli\u015ftirilebilmektedirler. Asenkron s\u00fcre\u00e7ler, senkron gidi\u015fata nazaran process \u00f6nceli\u011fini tahmin edilemeyecek bir \u015fekilde de\u011fi\u015ftirebilecek bir do\u011faya sahiptirler. Haliyle bu tahmin edilememezlik s\u00fcre\u00e7 esnas\u0131nda olas\u0131 bir\u00e7ok hatayla bizleri kar\u015f\u0131 kar\u015f\u0131ya b\u0131rakabilme ihtimaline sahiptirler. Dolay\u0131s\u0131yla bizler asenkron i\u015flemlerin ve olas\u0131 hatalar\u0131n s\u00f6z konusu oldu\u011fu bu belli ba\u015fl\u0131 durumlarda temelinde locking semantiklerini benimsemi\u015f s\u0131n\u0131flar\u0131 bar\u0131nd\u0131ran Thread Safe koleksiyonlar\u0131n\u0131 kullanarak muhtelif \u00f6nlemler almaktay\u0131z.<\/p>\n<p>Her\u015feyden \u00f6nce <em><strong>Thread Safe Nedir?<\/strong><\/em> sorusuna daha derin bir cevap vererek konuya ba\u015flayal\u0131m;<br \/>\n<em>Thread Safe<\/em>, anlam olarak <em>i\u015f par\u00e7ac\u0131\u011f\u0131 g\u00fcvenli\u011fi<\/em> \u015feklinde T\u00fcrk\u00e7e ifade edebilece\u011fimiz bir kavramd\u0131r. Thread Safe; birden \u00e7ok thread&#8217;in tekbir kayna\u011f\u0131 ayn\u0131 anda kullanabilmesi\/eri\u015febilmesi durumlar\u0131nda ortaya \u00e7\u0131kabilecek tutars\u0131zl\u0131klar neticesinde \u00fcretilecek olas\u0131 hatalara kar\u015f\u0131 o anki thread&#8217;in kayna\u011f\u0131n\u0131 g\u00fcvenceye alan ve bunu o kayna\u011f\u0131 kullanan t\u00fcm threadler i\u00e7in sa\u011flayan bir konsepttir.<\/p>\n<p>Yani anlayaca\u011f\u0131n\u0131z elimizdeki bir kayna\u011f\u0131 ayn\u0131 zamanda bir thread okurken bir ba\u015fka thread kaynaktaki veriler \u00fczerinde de\u011fi\u015fiklik yaparsa (yahut biri yazar bir di\u011feri silerse vs.) i\u015fte bu tarz asenkron durumlarda hatalar s\u00f6z konusu olacakt\u0131r. \u0130\u015fte bu hatalar\u0131 engellemek ve birden fazla threadin kulland\u0131\u011f\u0131 kaynak \u00fczerinde olu\u015fan de\u011fi\u015fiklikleri sadece o anda o de\u011fi\u015fikli\u011fi yapan threadin yapt\u0131\u011f\u0131n\u0131 d\u00fc\u015f\u00fcnd\u00fcrmek i\u00e7in Thread Safe ile gerekli \u00f6nlemler sa\u011flanmaktad\u0131r.<\/p>\n<p>Thread Safe konseptinin daha da iyi anla\u015f\u0131labilmesi i\u00e7in &#8220;erkekler tuvaletini&#8221; d\u00fc\u015f\u00fcnebilirsiniz \ud83d\ude42 Nas\u0131l ki, tuvaletteki pisuvar\u0131 o an kullanan ki\u015fi i\u015fini bitirmeden bir di\u011feri i\u015fine ba\u015flam\u0131yor hah i\u015fte buradaki rajonun vermi\u015f oldu\u011fu ahlak yaz\u0131l\u0131mda Thread Safe sayesinde ger\u00e7ekle\u015ftirilmektedir \ud83d\ude42 San\u0131r\u0131m bu \u00f6rnekle daha anla\u015f\u0131l\u0131r olmu\u015f olsa gerek&#8230;<\/p>\n<p>Bu olas\u0131 hatalar\u0131 man\u00fcp\u00fcle edebilmek, asenkron algoritmalar\u0131m\u0131zda verisel kar\u0131\u015f\u0131kl\u0131klarla maliyete sebep olmamak ve verimsel kesintiye u\u011fratmamak i\u00e7in .NET \u00e7at\u0131s\u0131nda Thread Safe koleksiyonlar\u0131 kullan\u0131lmaktad\u0131r. Bu koleksiyonlar <em><strong>System.Collections.Concurrent<\/strong><\/em> namespace&#8217;i alt\u0131nda bulunmaktad\u0131r ve <em>ConcurrentQueue<\/em>, <em>ConcurrentDictionary<\/em>, <em>ConcurrentBag<\/em>, <em>ConcurrentStack<\/em> ve <em>BlockingCollection<\/em> olmak \u00fczere be\u015f tanedir.<\/p>\n<p>Bu koleksiyonlar\u0131n ortak \u00f6zelli\u011fi <span style=\"color: orange;\">IProducerConsumerCollection&lt;T&gt;<\/span> aray\u00fcz\u00fcn\u00fc uygulamalar\u0131d\u0131r. Dikkat ederseniz \u00fcretici\/t\u00fcketici koleksiyonlar\u0131 ifade eden IProducerConsumerCollection aray\u00fcz\u00fc ilgili koleksiyona yeni bir eleman eklemek(\u00fcretmek) yahut eklenmi\u015f bir eleman\u0131 koleksiyondan \u00e7\u0131karmak(t\u00fcketmek) durumlar\u0131nda kullan\u0131l\u0131r.<\/p>\n<p>\u015eimdi gelin bu koleksiyonlar\u0131 s\u0131ras\u0131yla inceleyelim;<\/p>\n<ul>\n<li><strong><em>ConcurrentQueue&lt;T&gt;<\/em><\/strong><br \/>\nBirden fazla threadin e\u015f zamanl\u0131 bir \u015fekilde ayn\u0131 kaynak \u00fczerinde i\u015flem yapmas\u0131 durumunda, bir threadin yapt\u0131\u011f\u0131 de\u011fi\u015fiklikten dolay\u0131 bir di\u011ferinin patlamamas\u0131 ve birbirlerini ezmemesi i\u00e7in ConcurrentQueue koleksiyonu kullan\u0131labilir.\u00d6rne\u011fin a\u015fa\u011f\u0131daki senaryoyla durumu canland\u0131rabiliriz;<\/p>\n<blockquote><p>\u00dc\u00e7 masal\u0131 bir lokantada yo\u011funluktan dolay\u0131 yer problemi ya\u015fanmaktad\u0131r. Masalarda yer bo\u015fald\u0131k\u00e7a s\u0131radaki m\u00fc\u015fteri bo\u015falan yere al\u0131nmakta ve bu i\u015flem e\u015f zamanl\u0131 olarak t\u00fcm masalar i\u00e7in ger\u00e7ekle\u015ftirilmektedir.<\/p><\/blockquote>\n<p>Bu senaryo i\u00e7in a\u015fa\u011f\u0131daki geli\u015ftirmeyi yapt\u0131\u011f\u0131m\u0131z\u0131 d\u00fc\u015f\u00fcn\u00fcrsek;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static Queue siradakiler;\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            siradakiler = new Queue();\r\n            siradakiler.Enqueue(&quot;Ahmet&quot;);\r\n            siradakiler.Enqueue(&quot;Ali&quot;);\r\n            siradakiler.Enqueue(&quot;Mehmet&quot;);\r\n            siradakiler.Enqueue(&quot;Necati&quot;);\r\n            siradakiler.Enqueue(&quot;Ay\u015fe&quot;);\r\n            siradakiler.Enqueue(&quot;Mahmut&quot;);\r\n            siradakiler.Enqueue(&quot;Hilmi&quot;);\r\n            siradakiler.Enqueue(&quot;H\u00fcseyin&quot;);\r\n            siradakiler.Enqueue(&quot;R\u0131fk\u0131 Abi&quot;);\r\n\r\n            Kontrol().Wait();\r\n        }\r\n\r\n        static async Task Masa(string masaAdi)\r\n        {\r\n            while (siradakiler.Count &amp;gt; 0)\r\n            {\r\n                await Task.Delay(100);\r\n                Console.WriteLine($&quot;{masaAdi} - {siradakiler.Dequeue()}&quot;);\r\n            }\r\n        }\r\n\r\n        static async Task Kontrol()\r\n        {\r\n            var task1 = Masa(&quot;Masa 1&quot;);\r\n            var task2 = Masa(&quot;Masa 2&quot;);\r\n            var task3 = Masa(&quot;Masa 3&quot;);\r\n\r\n            await Task.WhenAll(task1, task2, task3);\r\n            Console.WriteLine(&quot;Masa s\u0131ras\u0131 bitmi\u015ftir.&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>Dikkat ederseniz, m\u00fc\u015fteri s\u0131ras\u0131n\u0131 Queue koleksiyonu ile tutmaktay\u0131z. Dolay\u0131s\u0131yla bu \u015fekilde e\u015f zamanl\u0131 bir \u00e7al\u0131\u015fman\u0131n oldu\u011fu bir senaryoda Queue koleksiyonunu kullanmak olas\u0131 hatalara kap\u0131 aralamakta ve kaynak \u00fczerinde bir thread taraf\u0131ndan de\u011fi\u015fiklik s\u00f6z konusu oldu\u011funda di\u011fer thread kayna\u011f\u0131n\u0131n de\u011fi\u015fti\u011fine dair \u00f6zellikle a\u015fa\u011f\u0131daki hatay\u0131 f\u0131rlatmaktad\u0131r;<\/p>\n<div style=\"text-align: center; color: orange;\"><strong><em>System.AggregateException: &#8216;One or more errors occurred. (Queue empty.)&#8217;<\/em><\/strong><\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11436\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"390\" height=\"99\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131.jpg 390w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-300x76.jpg 300w\" sizes=\"auto, (max-width: 390px) 100vw, 390px\" \/><\/a><br \/>\nKeza bu de\u011fi\u015fiklik &#8220;Kontrol&#8221; fonksiyonu i\u00e7erisinde asenkron bir \u015fekilde \u00e7al\u0131\u015ft\u0131r\u0131lan farkl\u0131 tasklar arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015ftirilmektedir.<\/p>\n<p>\u0130\u015fte b\u00f6yle bir senaryoda Queue koleksiyonu yerine ConcurrentQueue koleksiyonunu kullanabiliriz. ConcurrentQueue koleksiyonu; threadler aras\u0131nda soyutlamay\u0131 ger\u00e7ekle\u015ftirmekte ve kaynaktaki t\u00fcm elemanlar\u0131n sade ve sadece bir kereye mahsus bir task taraf\u0131ndan i\u015flenmesine m\u00fcsaade etmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static ConcurrentQueue&amp;lt;string&amp;gt; siradakiler;\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            siradakiler = new ConcurrentQueue&amp;lt;string&amp;gt;();\r\n            siradakiler.Enqueue(&quot;Ahmet&quot;);\r\n            siradakiler.Enqueue(&quot;Ali&quot;);\r\n            siradakiler.Enqueue(&quot;Mehmet&quot;);\r\n            siradakiler.Enqueue(&quot;Necati&quot;);\r\n            siradakiler.Enqueue(&quot;Ay\u015fe&quot;);\r\n            siradakiler.Enqueue(&quot;Mahmut&quot;);\r\n            siradakiler.Enqueue(&quot;Hilmi&quot;);\r\n            siradakiler.Enqueue(&quot;H\u00fcseyin&quot;);\r\n            siradakiler.Enqueue(&quot;R\u0131fk\u0131 Abi&quot;);\r\n\r\n            Kontrol().Wait();\r\n        }\r\n    \r\n        static async Task Masa(string masaAdi)\r\n        {\r\n            while (siradakiler.Count &amp;gt; 0)\r\n            {\r\n                await Task.Delay(100);\r\n                siradakiler.TryDequeue(out string siradaki);\r\n                Console.WriteLine($&quot;{masaAdi} - {siradaki}&quot;);\r\n            }\r\n        }\r\n\r\n        static async Task Kontrol()\r\n        {\r\n            var task1 = Masa(&quot;Masa 1&quot;);\r\n            var task2 = Masa(&quot;Masa 2&quot;);\r\n            var task3 = Masa(&quot;Masa 3&quot;);\r\n\r\n            await Task.WhenAll(task1, task2, task3);\r\n            Console.WriteLine(&quot;Masa s\u0131ras\u0131 bitmi\u015ftir.&quot;);\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer Queue yerine kullan\u0131lan ConcurrentQueue koleksiyonu &#8220;TryDequeue&#8221; fonksiyonu ile operasyonu ger\u00e7ekle\u015ftirmekte ve t\u00fcm threadleri \u00e7ak\u0131\u015ft\u0131rmaks\u0131z\u0131n s\u00fcreci ba\u015far\u0131yla sonland\u0131rabilmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11443\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"185\" height=\"166\" \/><\/a><\/li>\n<li><strong><em>ConcurrentDictionary&lt;TKey, TValue&gt;<\/em><\/strong><br \/>\n\u0130htiyac\u0131m\u0131z do\u011frultusunda \u00fcretilecek key &#8211; value konseptindeki ikili verileri bir asenkron operasyonla Dictionary koleksiyonunda toplama durumlar\u0131nda s\u00fcre\u00e7te m\u00fckerrer tan\u0131mlanmaya zorlanabilecek key de\u011ferlerine istinaden kar\u015f\u0131la\u015fabilece\u011fimiz olas\u0131 hatalara kar\u015f\u0131 ConcurrentDictionary koleksiyonunu tercih edebiliriz.Bu koleksiyonu a\u015fa\u011f\u0131daki senaryoyla \u00f6rneklendirebiliriz;<\/p>\n<blockquote><p>TSK b\u00fcnyesinde 100 ki\u015filik bir grubu da\u011f\u0131l\u0131m dengesini g\u00f6zetmeksizin rastgele bir \u015fekilde iki b\u00f6l\u00fc\u011fe ay\u0131rmak istiyoruz.<\/p><\/blockquote>\n<p>Burada her bir ki\u015fi say\u0131sal olarak key de\u011feriyle temsil edilecekken, kar\u015f\u0131l\u0131\u011f\u0131nada b\u00f6l\u00fck bilgisi value olarak atanacakt\u0131r. \u015eimdi bu i\u015flemi a\u015fa\u011f\u0131da ger\u00e7ekle\u015ftirelim;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static Dictionary&lt;int, string&gt; askerler;\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            askerler = new Dictionary&lt;int, string&gt;();\r\n            AtamaGerceklestir().Wait();\r\n            foreach (KeyValuePair&lt;int, string&gt; item in askerler)\r\n                Console.WriteLine($&quot;{item.Key} - {item.Value}&quot;);\r\n            Console.Read();\r\n        }\r\n\r\n        static async Task Ata(string bolukAdi)\r\n        {\r\n            for (int i = 1; i &lt;= 100; i++)\r\n            {\r\n                await Task.Delay(100);\r\n                if (!askerler.ContainsKey(i))\r\n                    askerler.TryAdd(i, bolukAdi);\r\n            }\r\n        }\r\n\r\n        static async Task AtamaGerceklestir()\r\n        {\r\n            var task1 = Ata(&quot;1. B\u00f6l\u00fck&quot;);\r\n            var task2 = Ata(&quot;2. B\u00f6l\u00fck&quot;);\r\n\r\n            await Task.WhenAll(task1, task2);\r\n        }\r\n    }\r\n<\/pre>\n<p>Bu \u015fekilde bir in\u015fa neticesinde a\u015fa\u011f\u0131daki hatayla kar\u015f\u0131la\u015fmak muhtemeldir.<\/p>\n<div style=\"text-align: center; color: orange;\"><strong><em>One or more errors occurred. (Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection&#8217;s state is no longer correct.)<\/em><\/strong><\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11453\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"361\" height=\"243\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg 361w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2-300x202.jpg 300w\" sizes=\"auto, (max-width: 361px) 100vw, 361px\" \/><\/a><br \/>\nBu olas\u0131 hatan\u0131n sebebi, asenkron operasyon esnas\u0131nda farkl\u0131 threadlar taraf\u0131ndan ilgili Dictionary i\u00e7erisinde m\u00fckerrer key de\u011ferlerinin \u00fcretilmeye \u00e7al\u0131\u015f\u0131lmas\u0131d\u0131r. \u00dcretilen ilgili key de\u011ferinin varl\u0131\u011f\u0131na dair 18. sat\u0131rda al\u0131nan \u00f6nlem o anki thread i\u00e7in eklemeye izin vermektedir. Dolay\u0131s\u0131yla ayn\u0131 anda ayn\u0131 key de\u011feri \u00fcretilmekte ve Dictionary koleksiyonuna eklenmekte\/eklenmeye \u00e7al\u0131\u015fmakta ve hakl\u0131 olarak patlama ya\u015fanmaktad\u0131r.<\/p>\n<p>\u0130\u015fte b\u00f6yle bir durumda, s\u00fcre\u00e7te asenkron i\u015flenen herhangi bir threade o anki key de\u011ferinin sade ve sadece kendisi taraf\u0131ndan \u00fcretildi\u011fini bildirecek ve di\u011fer threadlerin ezmesine m\u00fcsade etmeyecek olan thread safe f\u0131trat\u0131ndaki ConcurrentDictionary koleksiyonunu kullanmam\u0131z problemi \u00e7\u00f6zecek ve bizim yerimize gerekli kontrollerle organizasyonu sa\u011flayacakt\u0131r.<\/p>\n<p>\u0130lgili \u00e7al\u0131\u015fmay\u0131 a\u015fa\u011f\u0131daki gibi ConcurrentDictionary koleksiyonu ile tekrar tazelersek;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static ConcurrentDictionary&lt;int, string&gt; askerler;\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            askerler = new ConcurrentDictionary&lt;int, string&gt;();\r\n            AtamaGerceklestir().Wait();\r\n            foreach (KeyValuePair&lt;int, string&gt; item in askerler)\r\n                Console.WriteLine($&quot;{item.Key} - {item.Value}&quot;);\r\n            Console.Read();\r\n        }\r\n\r\n        static async Task Ata(string bolukAdi)\r\n        {\r\n            for (int i = 1; i &lt;= 100; i++)\r\n            {\r\n                await Task.Delay(100);\r\n                if (!askerler.ContainsKey(i))\r\n                    askerler.TryAdd(i, bolukAdi);\r\n            }\r\n        }\r\n\r\n        static async Task AtamaGerceklestir()\r\n        {\r\n            var task1 = Ata(&quot;1. B\u00f6l\u00fck&quot;);\r\n            var task2 = Ata(&quot;2. B\u00f6l\u00fck&quot;);\r\n\r\n            await Task.WhenAll(task1, task2);\r\n        }\r\n    }\r\n<\/pre>\n<p>Projeyi derleyip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda benzersiz key de\u011ferlerinin olu\u015fturuldu\u011funu ve kar\u015f\u0131l\u0131\u011f\u0131na gerekli value de\u011ferlerinin bas\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6receksiniz.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11459\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"125\" height=\"507\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3.jpg 125w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/07\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3-74x300.jpg 74w\" sizes=\"auto, (max-width: 125px) 100vw, 125px\" \/><\/a><\/li>\n<li><strong><em>ConcurrentBag&lt;T&gt;<\/em><\/strong><br \/>\nElimizdeki veri k\u00fcmesinde bulunan elemanlar\u0131 i\u015flerken s\u0131ralamay\u0131 g\u00f6z\u00f6n\u00fcne almad\u0131\u011f\u0131m\u0131z t\u00fcm i\u015flemlerde bu koleksiyon tercih edilebilir. Asenkron senaryolarda bu koleksiyon \u00fczerinde \u00e7al\u0131\u015fan t\u00fcm threadler i\u00e7in esas\u0131nda ilgili koleksiyondan bir model olu\u015fturulmakta ve her bir i\u015f par\u00e7ac\u0131\u011f\u0131 kendisine ait model \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan dolay\u0131 herhangi bir \u00e7ak\u0131\u015fma s\u00f6z konusu olmamaktad\u0131r.ConcurrentBag koleksiyonundan her eleman al\u0131nd\u0131\u011f\u0131nda Stack&#8217;te oldu\u011fu gibi listeye eklenen en sonuncu eleman elde edilecektir. Lakin burada vurgulanmas\u0131 gereken nokta \u015fudur ki; her bir thread i\u00e7in eklenen en son eleman kendisinde eklenen son elemand\u0131r. Dolay\u0131s\u0131yla n elemanl\u0131 bir koleksiyonda threadlerden birinde hi\u00e7 bir eleman eklenmedi ve en sonuncu eleman elde edilmeye \u00e7al\u0131\u015f\u0131ld\u0131ysa, i\u015fte b\u00f6yle bir durumda di\u011fer threadler taraf\u0131ndan son eleman olarak eklenenlerden birini <u>rastgele<\/u> alacak ve bizlere geri d\u00f6nd\u00fcrecektir. \u0130\u015fte b\u00f6yle bir durumda ConcurrentBag koleksiyonunun kullan\u0131ld\u0131\u011f\u0131 threadler aras\u0131nda \u00e7eki\u015fme s\u00f6z konusu olabilecektir.<\/p>\n<p>Bilakis ConcurrentBag koleksiyonuna yeni bir eleman eklenmek istendi\u011fi vakit s\u0131k\u0131nt\u0131s\u0131z s\u00fcre\u00e7 i\u015flenecek ve neticede threadlar aras\u0131 herhangi bir \u00e7ak\u0131\u015fma s\u00f6z konusu olmayaca\u011f\u0131ndan dolay\u0131 sa\u011fl\u0131kl\u0131 bir \u015fekilde ekleme i\u015flemi ger\u00e7ekle\u015ftirilecektir. Sadece Queue koleksiyonuna kar\u015f\u0131 bu i\u015flem biraz daha yava\u015f ger\u00e7ekle\u015ftirilecektir. Ama di\u011fer bir yandan Queue ve Stack koleksiyonlar\u0131nda da farkl\u0131 threadler \u00fczerinden eleman eklemek s\u00f6z konusu olmad\u0131\u011f\u0131ndan dolay\u0131 bu yava\u015fl\u0131k g\u00f6ze al\u0131nabilecek bir maliyet olarak de\u011ferlendirilebilmektedir.<\/p>\n<p>Velhas\u0131l&#8230; ConcurrentBag koleksiyonu, ekleme ve okuma i\u015flemleri i\u00e7in threadler \u00fczerinde e\u015fit bir da\u011f\u0131l\u0131m s\u00f6z konusuysa e\u011fer \u00e7ok faydal\u0131 olacakt\u0131r. Ayr\u0131ca yukar\u0131daki sat\u0131rlarda de\u011findi\u011fimiz gibi eleman elde etmek istendi\u011fi vakit ya ilgili thread taraf\u0131ndan en son eklenen eleman ya da di\u011fer threadlerden herhangi birinin ekledi\u011fi en sonucusu elimize ula\u015facakt\u0131r. \u0130\u015fte bu mant\u0131ktan dolay\u0131 o anda hangi eleman\u0131n i\u015flendi\u011finin \u00f6nemli olmad\u0131\u011f\u0131 senaryolarda g\u00f6n\u00fcl rahatl\u0131\u011f\u0131yla kullan\u0131labilecek bir koleksiyondur.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static ConcurrentBag&lt;int&gt; concurrentBag = new ConcurrentBag&lt;int&gt;();\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            AutoResetEvent autoResetEvent = new AutoResetEvent(false);\r\n            concurrentBag.Add(0);\r\n            #region Task 1\r\n            Task.Run(() =&gt;\r\n            {\r\n                Console.WriteLine(&quot;****&quot;);\r\n                for (int i = 1; i &lt; 10; i++) concurrentBag.Add(i); autoResetEvent.Set(); }); #endregion #region Task 2 Task.Run(() =&gt;\r\n              {\r\n                  Console.WriteLine(&quot;----&quot;);\r\n                  while (!concurrentBag.IsEmpty)\r\n                      if (concurrentBag.TryTake(out int data))\r\n                          Console.WriteLine(data);\r\n                  autoResetEvent.WaitOne();\r\n              });\r\n            #endregion\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p>Yukar\u0131daki \u00f6rnek kod blo\u011funu incelerseniz e\u011fer; iki farkl\u0131 taskta farkl\u0131 threadlar devreye sokulmu\u015f ve Task 1&#8217;de ConcurrentBag koleksiyonu doldurulurken Task 2&#8217;de ise ilgili koleksiyondaki de\u011ferler elde edilip ekrana yazd\u0131r\u0131lm\u0131\u015ft\u0131r. 5. sat\u0131rda koleksiyonumuza direkt olarak Main fonksiyonu i\u00e7erisinden bir eleman atanm\u0131\u015ft\u0131r. Nihayetinde bu atama i\u015fleminin Main&#8217;de olmas\u0131 demek Task 1&#8217;e nazaran farkl\u0131 threadde olmas\u0131 demektir. \u015eimdi bu kodu derleyip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131zda nas\u0131l bir sonu\u00e7la kar\u015f\u0131la\u015f\u0131yoruz inceleyelim ve \u00fczerine mant\u0131\u011f\u0131 hep beraber isti\u015fare edelim.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11469\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"53\" height=\"222\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11470\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"349\" height=\"221\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1.jpg 349w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-1-300x190.jpg 300w\" sizes=\"auto, (max-width: 349px) 100vw, 349px\" \/><\/a><\/p>\n<p>Yukar\u0131daki \u015femada belirtildi\u011fi gibi ilk olarak Task 1 devreye girse dahi s\u00fcre\u00e7 asenkron oldu\u011fu i\u00e7in her iki yap\u0131da birbirinden ba\u011f\u0131ms\u0131z e\u015f zamanl\u0131 bir \u015fekilde s\u00fcrece dahil olmakta ve i\u015flenmektedir. Burada ilk etapta &#8220;0&#8221; de\u011ferinin yazmas\u0131n\u0131 beklerken Task 1 i\u015flevi neticesinde koleksiyona dahil edilecek t\u00fcm de\u011ferlerin yaz\u0131ld\u0131\u011f\u0131n\u0131 g\u00f6rmekteyiz. Bunun nedeni &#8220;AutoResetEvent&#8221; s\u0131n\u0131f\u0131n\u0131n &#8220;WaitOne&#8221; metodu sayesinde Task 2 faaliyeti sona erdirilmeden asenkron s\u00fcre\u00e7teki di\u011fer fonksiyonlar(Task 1) devam ettirilmekte ve nihayetinde Task 1 i\u00e7erisinde yine ayn\u0131 s\u0131n\u0131f\u0131n &#8220;Set&#8221; metodu ile bekletilen thread s\u00fcrece devam ettirilmektedir. Haliyle koleksiyon i\u00e7erisindeki de\u011ferler de\u011fi\u015fse dahi Thread Safe koleksiyon olmas\u0131ndan dolay\u0131 kaynak revize edilse dahi bir hata meydana vermemekte ve yeni verileride while faaliyeti bir sonraki de\u011feri itere ederek elde edip \u00e7\u0131kt\u0131 olarak vermektedir. Ayr\u0131ca &#8220;0&#8221; de\u011ferinin en sonda elde edilmesi ise yukar\u0131daki sat\u0131rlarda a\u00e7\u0131klamaya \u00e7al\u0131\u015ft\u0131\u011f\u0131m\u0131z, her bir threadin kendi ekledi\u011fini en son olarak nitelemesi ve getirmesi olay\u0131n\u0131n a\u00e7\u0131k bir tezah\u00fcr\u00fcd\u00fcr. Neticede ilgili &#8220;0&#8221; de\u011ferini Task 1 de\u011fil Main thread&#8217;i eklemi\u015f bulunmaktad\u0131r.<\/p>\n<p>Bir ba\u015fka \u00f6rnek vermek gerekirse, s\u0131radan koleksiyon kullan\u0131lan operasyonlarda kaynak de\u011fi\u015fmesi durumunda al\u0131nacak olas\u0131 hatalar\u0131 ConcurrentBag ile rahatl\u0131kla a\u015fabildi\u011fimiz \u00fczerine verelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static List&lt;int&gt; sayilar = new List&lt;int&gt;();\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            Task.Run(() =&gt;\r\n              {\r\n                  for (int i = 1; i &lt;= 10; i++)\r\n                      sayilar.Add(i);\r\n                  int sayac = 0;\r\n                  while (sayac &lt; sayilar.Count) Console.WriteLine($&quot;{sayilar&#x5B;sayac++]}&quot;); }); Task.Run(() =&gt;\r\n            {\r\n                for (int i = 11; i &lt;= 20; i++)\r\n                    sayilar.Add(i);\r\n            });\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p>Yukar\u0131daki asenkron \u00e7al\u0131\u015fma neticesinde her iki threadin kulland\u0131\u011f\u0131 kaynak olan List koleksiyonu de\u011fi\u015fikli\u011fe u\u011frad\u0131\u011f\u0131 esnada a\u015fa\u011f\u0131daki olas\u0131 hatay\u0131 meydana getirebilir.<\/p>\n<div style=\"text-align: center; color: orange;\"><strong><em><br \/>\nSystem.ArgumentOutOfRangeException: &#8216;capacity was less than the current size.<br \/>\nParameter name: value&#8217;<br \/>\n<\/em><\/strong><\/div>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11479\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"362\" height=\"86\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2.jpg 362w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-2-300x71.jpg 300w\" sizes=\"auto, (max-width: 362px) 100vw, 362px\" \/><\/a><\/p>\n<p>Bu olas\u0131 hatalara mahal vermemek i\u00e7in ConcurrentBag kullan\u0131labilir;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static ConcurrentBag&lt;int&gt; concurrentBag = new ConcurrentBag&lt;int&gt;();\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            Task.Run(() =&gt;\r\n            {\r\n                for (int i = 1; i &lt;= 10; i++) concurrentBag.Add(i); while (concurrentBag.IsEmpty == false) if (concurrentBag.TryTake(out int data)) Console.WriteLine($&quot;{data}&quot;); }); Task.Run(() =&gt;\r\n            {\r\n                for (int i = 11; i &lt;= 20; i++)\r\n                    concurrentBag.Add(i);\r\n            });\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11482\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-3.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"28\" height=\"345\" \/><\/a><\/li>\n<li><strong><em>ConcurrentStack&lt;T&gt;<\/em><\/strong><br \/>\nAyn\u0131 kayna\u011f\u0131 kullanan en az iki thread\u0131n s\u00f6z konusu oldu\u011fu durumlarda bir thread ile kayna\u011fa veri eklerken bir di\u011feriyle silme i\u015flemlerinin ger\u00e7ekle\u015fti\u011fi senaryolarda ConcurrentStack koleksiyonu kullan\u0131labilir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static ConcurrentStack&lt;int&gt; concurrentStack = new ConcurrentStack&lt;int&gt;();\r\n        static AutoResetEvent autoResetEvent1 = new AutoResetEvent(false);\r\n        static AutoResetEvent autoResetEvent2 = new AutoResetEvent(false);\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            \/\/Ekle\r\n            Task.Run(() =&gt;\r\n            {\r\n                for (int i = 1; i &lt;= 10; i++) { concurrentStack.Push(i); autoResetEvent2.Set(); autoResetEvent1.WaitOne(); } autoResetEvent2.Set(); }); \/\/\u00c7\u0131kar Task.Run(() =&gt;\r\n            {\r\n                while (concurrentStack.IsEmpty)\r\n                {\r\n                    autoResetEvent2.WaitOne();\r\n                    if (concurrentStack.TryPop(out int item))\r\n                    {\r\n                        Console.WriteLine(item);\r\n                        autoResetEvent1.Set();\r\n                    }\r\n                }\r\n            });\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer; iki adet tan\u0131mlanan &#8220;AutoResetEvent&#8221; nesnesi arac\u0131l\u0131\u011f\u0131yla her iki thread&#8217;de ki ak\u0131\u015f senkronize edilmekte ve bu y\u00f6nlendirme ile ilgili koleksiyon i\u00e7erisine hem eleman eklenmekte hem de \u00e7\u0131kar\u0131lmaktad\u0131r.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-4.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11490\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-4.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"27\" height=\"190\" \/><\/a><\/li>\n<li><strong><em>BlockingCollection&lt;T&gt;<\/em><\/strong><br \/>\nVeri kayna\u011f\u0131n\u0131n bo\u015f oldu\u011fu durumlarda eleman talep edildi\u011fi vakit bir eleman ekleninceye kadar metot ak\u0131\u015f\u0131n\u0131 bekleten ve ba\u015fka bir thread taraf\u0131ndan ilgili kayna\u011fa eleman eklenince bu eleman\u0131 alarak geriye d\u00f6nd\u00fcren bir koleksiyondur. Ayriyetten bunlar\u0131n yan\u0131nda belirledi\u011fimiz kotay\u0131 a\u015famamas\u0131 i\u00e7in boyutu limitlenebilen bir koleksiyondur. BlockingCollection koleksiyonu farkl\u0131 overloadlar\u0131nda yukar\u0131da ele ald\u0131\u011f\u0131m\u0131z ConcurrentQueue, ConcurrentStack ve ConcurrentBag koleksiyonlar\u0131yla beraber \u00e7al\u0131\u015fmaktad\u0131r.<\/p>\n<p>\u015e\u00f6yle ki;<\/p>\n<ul>\n<li><em style=\"color:green;\">BlockingCollection&lt;T&gt;<\/em>; bu constructer kullan\u0131l\u0131yorsa e\u011fer arka planda bir ConcurrentQueue koleksiyonu olu\u015fturulmaktad\u0131r ve o noktadan itibaren ilgili koleksiyon mant\u0131\u011f\u0131nda \u00e7al\u0131\u015fmas\u0131na devam edecektir.\n<\/li>\n<li><em style=\"color:green;\">BlockingCollection&lt;T&gt;(Int32)<\/em>; bu constructer ise arka planda yukar\u0131daki gibi bir ConcurrentQueue koleksiyonu olu\u015fturmaktad\u0131r lakin ald\u0131\u011f\u0131 int parametresi sayesinde koleksiyonun boyutunu s\u0131n\u0131rland\u0131racakt\u0131r. E\u011fer ki, koleksiyonun limiti s\u0131n\u0131ra dayanm\u0131\u015f ise s\u00fcre\u00e7teki herhangi bir yeni eleman ekleme durumunda ilgili koleksiyon yer bo\u015falana kadar bekleyecek ve ilk f\u0131rsatta eklemeyi ger\u00e7ekle\u015ftirecektir.\n<\/li>\n<li><em style=\"color:green;\">BlockingCollection&lt;T&gt;(IProducerConsumerCollection&lt;T&gt;)<\/em>; ilgili koleksiyonu bir ConcurrentStack yahut ConcurrentBag mant\u0131\u011f\u0131nda de\u011ferlendirecektir.\n<\/li>\n<li><em style=\"color:green;\">BlockingCollection&lt;T&gt;(IProducerConsumerCollection&lt;T&gt;, Int32)<\/em>; bu constructer ise ilgili koleksiyonu ConcurrentStack yahut ConcurrentBag mant\u0131\u011f\u0131nda \u00e7al\u0131\u015ft\u0131racak ve bir yandan da boyut e\u015fi\u011fini belirlemi\u015f olacakt\u0131r.\n<\/li>\n<\/ul>\n<p>Bu bilgiler e\u015fli\u011finde a\u015fa\u011f\u0131daki kod blo\u011funu incelersek e\u011fer;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static BlockingCollection&lt;int&gt; blockingCollection = new BlockingCollection&lt;int&gt;();\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            int sayac = 10;\r\n            Task.Run(() =&gt;\r\n            {\r\n                while (sayac &gt;= 1) blockingCollection.Add(sayac--);\r\n            });\r\n\r\n            Task.Run(() =&gt;\r\n            {\r\n                while (sayac != 1) Console.WriteLine(blockingCollection.Take());\r\n            });\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-4.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-4.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"27\" height=\"190\" class=\"aligncenter size-full wp-image-11490\" \/><\/a><br \/>\nE\u011fer ilk devreye 2. task girerse koleksiyondaki de\u011ferleri okumaya \u00e7al\u0131\u015facak lakin ilk etapta koleksiyon i\u00e7erisinde eleman olmayaca\u011f\u0131ndan dolay\u0131 eklenmesini bekleyecek ve b\u00f6ylece 1. task devreye girdi\u011finde gerekli veriler koleksiyona set edilmi\u015f olacakt\u0131r. Netice olarak 2. task koleksiyon i\u00e7erisindeki elemanlar\u0131 tek tek elde edebilecektir.<\/p>\n<p>Son olarak yukar\u0131daki kod blo\u011funda bir hususa dikkat \u00e7ekersek e\u011fer tan\u0131mlanan tasklar global saya\u00e7 de\u011fi\u015fkeniyle d\u00f6ng\u00fcleri kontrol etmektedirler. Dolay\u0131s\u0131yla bu \u015fekilde bizler BlockingCollection k\u00fct\u00fcphanesinin yeni veri eklenmesine dair ihtiyac\u0131n\u0131 hissetmemekteyiz. E\u011fer ki, BlockingCollection koleksiyonuna eklenecek olan verinin sonuna gelindi\u011fine dair bilgi vermek istiyorsak ekleme i\u015fleminden sonra CompleteAdding metodunu \u00e7a\u011f\u0131rman\u0131z yeterlidir. Bu metot \u00e7a\u011fr\u0131ld\u0131ktan sonraki ilk Take talebinde InvalidOperationException hatas\u0131 f\u0131rlat\u0131lacak ve b\u00f6ylece yeni bir veri girilmesine dair beklenti sona erecektir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        static BlockingCollection&lt;int&gt; blockingCollection = new BlockingCollection&lt;int&gt;();\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            int sayac = 10;\r\n            Task.Run(() =&gt;\r\n            {\r\n                while (sayac &gt;= 1) blockingCollection.Add(sayac--);\r\n                blockingCollection.CompleteAdding();\r\n            });\r\n\r\n            Task.Run(() =&gt;\r\n            {\r\n                try\r\n                {\r\n                    while (true) Console.WriteLine(blockingCollection.Take());\r\n                }\r\n                catch (InvalidOperationException ex)\r\n                {\r\n                    Console.WriteLine(ex.Message);\r\n                }\r\n            });\r\n\r\n            Console.Read();\r\n        }\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"1170\" height=\"476\" class=\"aligncenter size-full wp-image-11510\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5.jpg 1170w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5-300x122.jpg 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5-768x312.jpg 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-5-1024x417.jpg 1024w\" sizes=\"auto, (max-width: 1170px) 100vw, 1170px\" \/><\/a>\n<\/li>\n<\/ul>\n<p>Netice olarak son bir de\u011ferlendirmeye mazhar olmam\u0131z gerekirse e\u011fer inceledi\u011fimiz bu Thread Safe koleksiyonlar\u0131 performans a\u00e7\u0131s\u0131ndan normal koleksiyonlara nazaran olduk\u00e7a d\u00fc\u015f\u00fck seviyede \u00e7al\u0131\u015fmakta ve maliyeti artt\u0131rmaktad\u0131rlar. Bu koleksiyonlar\u0131 asenkron operasyonlar dahilinde yukar\u0131da de\u011findi\u011fimiz senaryolara uygun bir \u015fekilde de\u011ferlendirmenizi ve yersiz bir \u015fekilde kullan\u0131m\u0131ndan ka\u00e7\u0131nman\u0131z\u0131 \u00f6nemle vurguluyorum.<br \/>\n<div id=\"attachment_11512\" style=\"width: 551px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-6.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-11512\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-6.jpg\" alt=\"Thread Safe - ConcurrentQueue, ConcurrentDictionary, ConcurrentBag ve ConcurrentStack Koleksiyonlar\u0131 ve Kullan\u0131m Durumlar\u0131\" width=\"541\" height=\"216\" class=\"size-full wp-image-11512\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-6.jpg 541w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2019\/08\/Thread-Safe-ConcurrentQueue-ConcurrentDictionary-ConcurrentBag-ve-ConcurrentStack-Koleksiyonlar\u0131-ve-Kullan\u0131m-Durumlar\u0131-6-300x120.jpg 300w\" sizes=\"auto, (max-width: 541px) 100vw, 541px\" \/><\/a><p id=\"caption-attachment-11512\" class=\"wp-caption-text\">Thread Safe &#8211; E\u015fzamanl\u0131 Koleksiyonlar\u0131n performans \u00f6l\u00e7\u00fcs\u00fc<\/p><\/div><\/p>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle\u2026<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere\u2026<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar\u2026<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Yaz\u0131l\u0131msal problemlere \u00e7\u00f6z\u00fcm olarak geli\u015ftirdi\u011fimiz algoritmalar ihtiyaca d\u00f6n\u00fck olarak yer yer asenkron i\u015flevde geli\u015ftirilebilmektedirler. Asenkron s\u00fcre\u00e7ler, senkron gidi\u015fata nazaran process \u00f6nceli\u011fini tahmin edilemeyecek bir \u015fekilde de\u011fi\u015ftirebilecek bir do\u011faya sahiptirler. Haliyle bu tahmin edilememezlik&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":11513,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2739,12],"tags":[2943,2947,2948,2941,2940,2939,2942,2949,1177,2946,2944,2938,2936,2937,2945],"class_list":["post-11408","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-net-core","category-c-sharp-c","tag-autoresetevent","tag-blockingcollection","tag-completeadding","tag-concurrentbag","tag-concurrentdictionary","tag-concurrentqueue","tag-concurrentstack","tag-eszamanli-koleksiyonlar","tag-invalidoperationexception","tag-iproducerconsumercollection","tag-set","tag-system-collections-concurrent","tag-thread-safe","tag-thread-safe-nedir","tag-waitone"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11408","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=11408"}],"version-history":[{"count":94,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11408\/revisions"}],"predecessor-version":[{"id":11514,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/11408\/revisions\/11514"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/11513"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=11408"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=11408"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=11408"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}