线程安全集合ConcurrentDictionary和ConcurrentQueue

1、ConcurrentDictionary

    class Program
    {
        static void Main(string[] args)
        {
            string[] urls = new string[] {
                "https://www.cnblogs.com",
                "http://msdn.microsoft.com",
                "http://www.microsoft.com"
            };

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            var downloads = from url in urls
                            select CachedDownloads.DownloadStringAsync(url);
            Task.WhenAll(downloads).ContinueWith(results =>
            {
                stopwatch.Stop();
                Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
                    results.Result.Sum(result=>result.Length),
                    stopwatch.ElapsedMilliseconds);
            }).Wait();

            stopwatch.Restart();
            downloads = from url in urls
                        select CachedDownloads.DownloadStringAsync(url);
            Task.WhenAll(downloads).ContinueWith(results =>
            {
                stopwatch.Stop();
                Console.WriteLine("Retrieved {0} characters. Elapsed time was {1} ms.",
                    results.Result.Sum(result => result.Length),
                    stopwatch.ElapsedMilliseconds);
            }).Wait();
            Console.Read();
        }
    }

    class CachedDownloads
    {
        /// <summary>
        /// 将下载在操作的结果保存在线程安全的集合中
        /// </summary>
        static ConcurrentDictionary<string, string> cachedDownloads = new ConcurrentDictionary<string, string>();

        public static Task<string> DownloadStringAsync(string address)
        {
            // 首先尝试从缓存中检索内容
            string content;
            if (cachedDownloads.TryGetValue(address, out content))
            {
                return Task.FromResult<string>(content);
            }
            return Task.Run(async () =>
            {
                var client = new WebClient();
                client.Headers.Add("user-agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
                content = await client.DownloadStringTaskAsync(address);
                cachedDownloads.TryAdd(address, content);
                return content;
            });
        }
    }
View Code

2、ConcurrentQueue

            // Construct a ConcurrentQueue.
            ConcurrentQueue<int> cq = new ConcurrentQueue<int>();

            // Populate the queue.
            for (int i = 0; i < 10000; i++) cq.Enqueue(i);

            int result;
            if (!cq.TryPeek(out result))
            {
                Console.WriteLine("CQ: TryPeek failed when it should have succeeded");
            }
            else if (result != 0)
            {
                Console.WriteLine("CQ: Expected TryPeek result of 0, got {0}", result);
            }

            int outerSum = 0;
            Action action = () =>
            {
                int localSum = 0;
                int localValue;
                while (cq.TryDequeue(out localValue)) localSum += localValue;
                Interlocked.Add(ref outerSum, localSum);
            };
            Parallel.Invoke(action, action, action, action);
            Console.WriteLine("outerSum = {0}, should be 49995000", outerSum);
            Console.Read();
View Code

 

posted @ 2022-01-17 15:20  江境纣州  阅读(35)  评论(0编辑  收藏  举报