csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll相关的知识,希望对你有一定的参考价值。
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class ConcurrentBagProgram
{
static void Main(string[] args)
{
//表示实现的是一个无序的集合类
//该类有两个重要的方法用来访问队列中的元素.分别是:
//TryTake 尝试移除并返回位于队列头开始处的对象.
//TryPeek尝试返回位于队列头开始处的对象但不将其移除.
ConcurrentBag<int> sharedBag = new ConcurrentBag<int>();
for (int i = 0; i < 1000; i++)
{
sharedBag.Add(i);
}
int itemCount = 0;
Task[] tasks = new Task[10];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while (sharedBag.Count > 0)
{
int queueElement;
bool gotElement = sharedBag.TryTake(out queueElement);
if (gotElement)
Interlocked.Increment(ref itemCount);
}
});
tasks[i].Start();
}
Task.WaitAll(tasks);
Console.WriteLine("Items processed:{0}", itemCount);
Console.WriteLine("Press Enter to finish");
Console.WriteLine(itemCount);
Console.ReadLine();
}
}
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
class ConcurrentQueueProgram
{
static void Main(string[] args)
{
//表示线程安全的先进先出(FIFO)队列
//TryDequeue 尝试移除并返回位于队列头开始处的对象.
//TryPeek尝试返回位于队列头开始处的对象但不将其移除.
ConcurrentQueue<int> sharedQueue = new ConcurrentQueue<int>();
for (int i = 0; i < 1000000; i++)
{
sharedQueue.Enqueue(i);
}
int itemCount = 0;
Task[] tasks = new Task[10];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = new Task(() =>
{
while (sharedQueue.Count > 0)
{
int queueElement;
bool gotElement = sharedQueue.TryDequeue(out queueElement);
if (gotElement)
{
Interlocked.Increment(ref itemCount);
}
}
});
tasks[i].Start();
}
Task.WaitAll(tasks);
Console.WriteLine("Items processed:{0}", itemCount);
Console.WriteLine("Press Enter to finish");
Console.WriteLine(itemCount);
Console.ReadLine();
}
}
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
// 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合.因此当有多个线程并发访问集合时,应首先考虑使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型
class BankAccount
{
public int Balance
{
get;
set;
}
}
class ConcurrentBagProgram
{
static void Main(string[] args)
{
//实现的是一个键 - 值集合类.它提供的方法有:
//TryAdd:尝试向集合添加一个键 - 值
//TryGetValue:尝试返回指定键的值.
//TryRemove:尝试移除指定键处的元素.
//TryUpdate:尝试更新指定键的值.
BankAccount account = new BankAccount();
ConcurrentDictionary<object, int> sharedDict = new ConcurrentDictionary<object, int>();
Task<int>[] tasks = new Task<int>[10];
for (int i = 0; i < tasks.Length; i++)
{
sharedDict.TryAdd(i, account.Balance);
tasks[i] = new Task<int>((keyObj) =>
{
int currentValue;
bool gotValue;
for (int j = 0; j < 1000; j++)
{
gotValue = sharedDict.TryGetValue(keyObj, out currentValue);
sharedDict.TryUpdate(keyObj, currentValue + 1, currentValue);
}
int result;
gotValue = sharedDict.TryGetValue(keyObj, out result);
if (gotValue)
{
return result;
}
else
{
throw new Exception(String.Format("No data item available for key {0}", keyObj));
}
}, i);
tasks[i].Start();
}
for(int i = 0; i < tasks.Length; i++)
{
account.Balance += tasks[i].Result;
}
Console.WriteLine("Expected value {0}, Balance: {1}", 10000, account.Balance);
Console.WriteLine("Press enter to finish");
Console.WriteLine(account.Balance);
Console.ReadLine();
}
}
}
以上是关于csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll的主要内容,如果未能解决你的问题,请参考以下文章