BitArraySample
using System; using System.Collections; using System.Collections.Specialized; using System.Text; namespace BitArraySample { class Program { static void BitArrayDemo() { var bits1 = new BitArray(8); bits1.SetAll(true); bits1.Set(1, false); bits1[5] = false; bits1[7] = false; Console.Write("initialized: "); DisplayBits(bits1); Console.WriteLine(); DisplayBits(bits1); bits1.Not(); Console.Write(" not "); DisplayBits(bits1); Console.WriteLine(); var bits2 = new BitArray(bits1); bits2[0] = true; bits2[1] = false; bits2[4] = true; DisplayBits(bits1); Console.Write(" or "); DisplayBits(bits2); Console.Write(" : "); bits1.Or(bits2); DisplayBits(bits1); Console.WriteLine(); DisplayBits(bits2); Console.Write(" and "); DisplayBits(bits1); Console.Write(" : "); bits2.And(bits1); DisplayBits(bits2); Console.WriteLine(); DisplayBits(bits1); Console.Write(" xor "); DisplayBits(bits2); bits1.Xor(bits2); Console.Write(" : "); DisplayBits(bits1); Console.WriteLine(); } static void BitVectorDemo() { var bits1 = new BitVector32(); int bit1 = BitVector32.CreateMask(); int bit2 = BitVector32.CreateMask(bit1); int bit3 = BitVector32.CreateMask(bit2); int bit4 = BitVector32.CreateMask(bit3); int bit5 = BitVector32.CreateMask(bit4); bits1[bit1] = true; bits1[bit2] = false; bits1[bit3] = true; bits1[bit4] = true; Console.WriteLine(bits1); bits1[0xabcdef] = true; Console.WriteLine(bits1); int received = 0x79abcdef; var bits2 = new BitVector32(received); Console.WriteLine(bits2); // sections: FF EEE DDD CCCC BBBBBBBB AAAAAAAAAAAA BitVector32.Section sectionA = BitVector32.CreateSection(0xfff); BitVector32.Section sectionB = BitVector32.CreateSection(0xff, sectionA); BitVector32.Section sectionC = BitVector32.CreateSection(0xf, sectionB); BitVector32.Section sectionD = BitVector32.CreateSection(0x7, sectionC); BitVector32.Section sectionE = BitVector32.CreateSection(0x7, sectionD); BitVector32.Section sectionF = BitVector32.CreateSection(0x3, sectionE); Console.WriteLine("Section A: " + IntToBinaryString(bits2[sectionA], true)); Console.WriteLine("Section B: " + IntToBinaryString(bits2[sectionB], true)); Console.WriteLine("Section C: " + IntToBinaryString(bits2[sectionC], true)); Console.WriteLine("Section D: " + IntToBinaryString(bits2[sectionD], true)); Console.WriteLine("Section E: " + IntToBinaryString(bits2[sectionE], true)); Console.WriteLine("Section F: " + IntToBinaryString(bits2[sectionF], true)); } static string IntToBinaryString(int bits, bool removeTrailingZero) { var sb = new StringBuilder(32); for (int i = 0; i < 32; i++) { if ((bits & 0x80000000) != 0) { sb.Append("1"); } else { sb.Append("0"); } bits = bits << 1; } string s = sb.ToString(); if (removeTrailingZero) return s.TrimStart('0'); else return s; } static void Main() { // BitArrayDemo(); BitVectorDemo(); } static void DisplayBits(BitArray bits) { foreach (bool bit in bits) { Console.Write(bit ? 1 : 0); } } } }
ConcurrentSample
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { public class Info { public string Word { get; set; } public int Count { get; set; } public string Color { get; set; } public override string ToString() { return String.Format("{0} x: {1}", Count, Word); } } }
using System; using System.Collections.Concurrent; using System.IO; using System.Threading; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { // BlockingDemo(); //BlockingDemoSimple(); PipelineSample(); Console.ReadLine(); } private static void ReadFileNames(string path, BlockingCollection<string> output) { foreach (string filename in Directory.EnumerateFiles(path, "*.cs")) { output.Add(filename); } output.CompleteAdding(); } private static void AddOrIncrementValue(string key, ConcurrentDictionary<string, int> dict) { bool success = false; while (!success) { int value; if (dict.TryGetValue(key, out value)) { if (dict.TryUpdate(key, value + 1, value)) { success = true; } } else { if (dict.TryAdd(key, 1)) { success = true; } } } } private static async void LoadContent(BlockingCollection<string> input, ConcurrentDictionary<string, int> output) { foreach (var filename in input.GetConsumingEnumerable()) { using (FileStream stream = File.OpenRead(filename)) { var reader = new StreamReader(stream); string line = await reader.ReadLineAsync(); string[] words = line.Split(' ', ';', ' '); foreach (var word in words) { AddOrIncrementValue(word, output); } } } } private static void TransferContent(ConcurrentDictionary<string, int> input, BlockingCollection<Info> output) { foreach (var word in input.Keys) { int value; if (input.TryGetValue(word, out value)) { output.Add(new Info { Word = word, Count = value }); } } } private static void ShowContent(BlockingCollection<Info> input) { foreach (var item in input.GetConsumingEnumerable()) { Console.WriteLine(item); } } private static async void PipelineSample() { BlockingCollection<string> coll1 = new BlockingCollection<string>(); ConcurrentDictionary<string, int> coll2 = new ConcurrentDictionary<string,int>(); BlockingCollection<Info> coll3 = new BlockingCollection<Info>(); Task t1 = Task.Factory.StartNew(() => ReadFileNames(@"C: empMvcApplication1MvcApplication1Controllers", coll1), TaskCreationOptions.LongRunning); Console.WriteLine("started stage 1"); Task t2 = Task.Factory.StartNew(() => LoadContent(coll1, coll2), TaskCreationOptions.LongRunning); Console.WriteLine("started stage 2"); await Task.WhenAll(t1, t2); Console.WriteLine("stage 1 and 2 completed"); Task t3 = Task.Factory.StartNew(() => TransferContent(coll2, coll3), TaskCreationOptions.LongRunning); Task t4 = Task.Factory.StartNew(() => ShowContent(coll3), TaskCreationOptions.LongRunning); Console.WriteLine("stages 3 and 4 started"); await Task.WhenAll(t3, t4); Console.WriteLine("all finished"); } static void BlockingDemoSimple() { var sharedCollection = new BlockingCollection<int>(); var events = new ManualResetEventSlim[2]; var waits = new WaitHandle[2]; for (int i = 0; i < 2; i++) { events[i] = new ManualResetEventSlim(false); waits[i] = events[i].WaitHandle; } var producer = new Thread(obj => { var state = (Tuple<BlockingCollection<int>, ManualResetEventSlim>)obj; var coll = state.Item1; var ev = state.Item2; var r = new Random(); for (int i = 0; i < 300; i++) { coll.Add(r.Next(3000)); } ev.Set(); }); producer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[0])); var consumer = new Thread(obj => { var state = (Tuple<BlockingCollection<int>, ManualResetEventSlim>)obj; var coll = state.Item1; var ev = state.Item2; for (int i = 0; i < 300; i++) { int result = coll.Take(); } ev.Set(); }); consumer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[1])); if (!WaitHandle.WaitAll(waits)) Console.WriteLine("wait failed"); else Console.WriteLine("reading/writing finished"); } static async void BlockingDemo() { const int taskCount = 10; ManualResetEventSlim[] events = new ManualResetEventSlim[taskCount]; WaitHandle[] waits = new WaitHandle[taskCount]; var consoleLock = new object(); for (int task = 0; task < taskCount; task++) { events[task] = new ManualResetEventSlim(false); waits[task] = events[task].WaitHandle; } var sharedCollection = new BlockingCollection<int>(); for (int task = 0; task < taskCount >> 1; task++) { var producer = new Task((state) => { var coll = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item1; var wait = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item2; var r = new Random(); for (int i = 0; i < 300; i++) { int data = r.Next(30000); if (!coll.TryAdd(data)) { Console.WriteLine("**** couldn't add"); } else { lock (consoleLock) { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(" {0} ", data); Console.ResetColor(); } } Thread.Sleep(r.Next(40)); } wait.Set(); }, Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task])); producer.Start(); // producer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task])); } await Task.Delay(500); // give the producers a headstart for (int task = taskCount >> 1; task < taskCount; task++) { var consumer = new Task((state) => { var coll = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item1; var wait = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item2; var r = new Random(); for (int i = 0; i < 3000; i++) { int result; if (!coll.TryTake(out result)) { Console.WriteLine("couldn't take"); } else { lock (consoleLock) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(" {0} ", result); Console.ResetColor(); } } Thread.Sleep(r.Next(40)); } wait.Set(); }, Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task])); consumer.Start(); } if (!WaitHandle.WaitAll(waits)) Console.WriteLine("error waiting..."); } } }
DictionarySample
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var employees = new Dictionary<EmployeeId, Employee>(31); var idTony = new EmployeeId("C3755"); var tony = new Employee(idTony, "Tony Stewart", 379025.00m); employees.Add(idTony, tony); Console.WriteLine(tony); var idCarl = new EmployeeId("F3547"); var carl = new Employee(idCarl, "Carl Edwards", 403466.00m); employees.Add(idCarl, carl); Console.WriteLine(carl); var idKevin = new EmployeeId("C3386"); var kevin = new Employee(idKevin, "Kevin Harwick", 415261.00m); employees.Add(idKevin, kevin); Console.WriteLine(kevin); var idMatt = new EmployeeId("F3323"); var matt = new Employee(idMatt, "Matt Kenseth", 1589390.00m); employees[idMatt] = matt; Console.WriteLine(matt); var idBrad = new EmployeeId("D3234"); var brad = new Employee(idBrad, "Brad Keselowski", 322295.00m); employees[idBrad] = brad; Console.WriteLine(brad); while (true) { Console.Write("Enter employee id (X to exit)> "); var userInput = Console.ReadLine(); userInput = userInput.ToUpper(); if (userInput == "X") break; EmployeeId id; try { id = new EmployeeId(userInput); Employee employee; if (!employees.TryGetValue(id, out employee)) { Console.WriteLine("Employee with id {0} does not exist", id); } else { Console.WriteLine(employee); } } catch (EmployeeIdException ex) { Console.WriteLine(ex.Message); } } } } }
using System; using System.Diagnostics.Contracts; namespace Wrox.ProCSharp.Collections { [Serializable] public class EmployeeIdException : Exception { public EmployeeIdException(string message) : base(message) { } } [Serializable] public struct EmployeeId : IEquatable<EmployeeId> { private readonly char prefix; private readonly int number; public EmployeeId(string id) { Contract.Requires<ArgumentNullException>(id != null); prefix = (id.ToUpper())[0]; int numLength = id.Length - 1; try { number = int.Parse(id.Substring(1, numLength > 6 ? 6 : numLength)); } catch (FormatException) { throw new EmployeeIdException("Invalid EmployeeId format"); } } public override string ToString() { return prefix.ToString() + string.Format("{0,6:000000}", number); } public override int GetHashCode() { return (number ^ number << 16) * 0x15051505; } public bool Equals(EmployeeId other) { if (other == null) return false; return (prefix == other.prefix && number == other.number); } public override bool Equals(object obj) { return Equals((EmployeeId)obj); } public static bool operator ==(EmployeeId left, EmployeeId right) { return left.Equals(right); } public static bool operator !=(EmployeeId left, EmployeeId right) { return !(left == right); } } }
using System; namespace Wrox.ProCSharp.Collections { [Serializable] public class Employee { private string name; private decimal salary; private readonly EmployeeId id; public Employee(EmployeeId id, string name, decimal salary) { this.id = id; this.name = name; this.salary = salary; } public override string ToString() { return String.Format("{0}: {1, -20} {2:C}", id.ToString(), name, salary); } } }
ImmutableCollectionsSample
using System; using System.Collections.Generic; using System.Collections.Immutable; namespace ImmutableCollectionsSample { class Program { static void Main(string[] args) { // ArraySample(); ListSample(); Console.ReadKey(); } private static void ListSample() { List<Account> accounts = new List<Account>() { new Account { Name = "Scrooge McDuck", Amount = 667377678765m }, new Account { Name = "Donald Duck", Amount = -200m }, new Account { Name = "Ludwig von Drake", Amount = 20000m }}; ImmutableList<Account> immutableAccounts = accounts.ToImmutableList(); ImmutableList<Account>.Builder builder = immutableAccounts.ToBuilder(); for (int i = 0; i < builder.Count; i++) { Account a = builder[i]; if (a.Amount > 0) { builder.Remove(a); } } ImmutableList<Account> overdrawnAccounts = builder.ToImmutable(); foreach (var item in overdrawnAccounts) { Console.WriteLine("{0} {1}", item.Name, item.Amount); } } private static void ArraySample() { ImmutableArray<string> a1 = ImmutableArray.Create<string>(); ImmutableArray<string> a2 = a1.Add("Williams"); ImmutableArray<string> a3 = a2.Add("Ferrari").Add("Mercedes").Add("Red Bull Racing"); foreach (var item in a3) { Console.WriteLine(item); } } } }
namespace ImmutableCollectionsSample { public class Account { public string Name { get; set; } public decimal Amount { get; set; } } }
LinkedListSample
using System; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { PriorityDocumentManager pdm = new PriorityDocumentManager(); pdm.AddDocument(new Document("one", "Sample", 8)); pdm.AddDocument(new Document("two", "Sample", 3)); pdm.AddDocument(new Document("three", "Sample", 4)); pdm.AddDocument(new Document("four", "Sample", 8)); pdm.AddDocument(new Document("five", "Sample", 1)); pdm.AddDocument(new Document("six", "Sample", 9)); pdm.AddDocument(new Document("seven", "Sample", 1)); pdm.AddDocument(new Document("eight", "Sample", 1)); pdm.DisplayAllNodes(); Console.ReadKey(); } } }
using System; using System.Collections.Generic; using System.Diagnostics.Contracts; namespace Wrox.ProCSharp.Collections { public class PriorityDocumentManager { private readonly LinkedList<Document> documentList; // priorities 0.9 private readonly List<LinkedListNode<Document>> priorityNodes; public PriorityDocumentManager() { documentList = new LinkedList<Document>(); priorityNodes = new List<LinkedListNode<Document>>(10); for (int i = 0; i < 10; i++) { priorityNodes.Add(new LinkedListNode<Document>(null)); } } public void AddDocument(Document d) { //Contract.Requires<ArgumentNullException>(d != null, "argument d must not be null"); if (d == null) throw new ArgumentNullException("d"); AddDocumentToPriorityNode(d, d.Priority); } private void AddDocumentToPriorityNode(Document doc, int priority) { //Contract.Requires<ArgumentException>(priority >= 0 && priority < 10, "priority value must be between 0 and 9"); if (priority > 9 || priority < 0) throw new ArgumentException("Priority must be between 0 and 9"); if (priorityNodes[priority].Value == null) { --priority; if (priority >= 0) { // check for the next lower priority AddDocumentToPriorityNode(doc, priority); } else // now no priority node exists with the same priority or lower // add the new document to the end { documentList.AddLast(doc); priorityNodes[doc.Priority] = documentList.Last; } return; } else // a priority node exists { LinkedListNode<Document> prioNode = priorityNodes[priority]; if (priority == doc.Priority) // priority node with the same priority exists { documentList.AddAfter(prioNode, doc); // set the priority node to the last document with the same priority priorityNodes[doc.Priority] = prioNode.Next; } else // only priority node with a lower priority exists { // get the first node of the lower priority LinkedListNode<Document> firstPrioNode = prioNode; while (firstPrioNode.Previous != null && firstPrioNode.Previous.Value.Priority == prioNode.Value.Priority) { firstPrioNode = prioNode.Previous; prioNode = firstPrioNode; } documentList.AddBefore(firstPrioNode, doc); // set the priority node to the new value priorityNodes[doc.Priority] = firstPrioNode.Previous; } } } public void DisplayAllNodes() { foreach (Document doc in documentList) { Console.WriteLine("priority: {0}, title {1}", doc.Priority, doc.Title); } } // returns the document with the highest priority // (that's first in the linked list) public Document GetDocument() { Document doc = documentList.First.Value; documentList.RemoveFirst(); return doc; } } }
namespace Wrox.ProCSharp.Collections { public class Document { public string Title { get; private set; } public string Content { get; private set; } public byte Priority { get; private set; } public Document(string title, string content, byte priority) { this.Title = title; this.Content = content; this.Priority = priority; } } }
ListSamples
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.Collections { public enum CompareType { FirstName, LastName, Country, Wins } public class RacerComparer : IComparer<Racer> { private CompareType compareType; public RacerComparer(CompareType compareType) { this.compareType = compareType; } public int Compare(Racer x, Racer y) { if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; int result; switch (compareType) { case CompareType.FirstName: return string.Compare(x.FirstName, y.FirstName); case CompareType.LastName: return string.Compare(x.LastName, y.LastName); case CompareType.Country: result = string.Compare(x.Country, y.Country); if (result == 0) return string.Compare(x.LastName, y.LastName); else return result; case CompareType.Wins: return x.Wins.CompareTo(y.Wins); default: throw new ArgumentException("Invalid Compare Type"); } } } }
using System; namespace Wrox.ProCSharp.Collections { [Serializable] public class Racer : IComparable<Racer>, IFormattable { public int Id { get; private set; } public string FirstName { get; set; } public string LastName { get; set; } public string Country { get; set; } public int Wins { get; set; } public Racer(int id, string firstName, string lastName, string country) : this(id, firstName, lastName, country, wins: 0) { } public Racer(int id, string firstName, string lastName, string country, int wins) { this.Id = id; this.FirstName = firstName; this.LastName = lastName; this.Country = country; this.Wins = wins; } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "N"; switch (format.ToUpper()) { case null: case "N": // name return ToString(); case "F": // first name return FirstName; case "L": // last name return LastName; case "W": // Wins return String.Format("{0}, Wins: {1}", ToString(), Wins); case "C": // Country return String.Format("{0}, Country: {1}", ToString(), Country); case "A": // All return String.Format("{0}, {1} Wins: {2}", ToString(), Country, Wins); default: throw new FormatException(String.Format(formatProvider, "Format {0} is not supported", format)); } } public string ToString(string format) { return ToString(format, null); } public int CompareTo(Racer other) { if (other == null) return -1; int compare = string.Compare(this.LastName, other.LastName); if (compare == 0) return string.Compare(this.FirstName, other.FirstName); return compare; } } }
using System.Collections.Generic; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var graham = new Racer(7, "Graham", "Hill", "UK", 14); var emerson = new Racer(13, "Emerson", "Fittipaldi", "Brazil", 14); var mario = new Racer(16, "Mario", "Andretti", "USA", 12); var racers = new List<Racer>(20) { graham, emerson, mario }; racers.Add(new Racer(24, "Michael", "Schumacher", "Germany", 91)); racers.Add(new Racer(27, "Mika", "Hakkinen", "Finland", 20)); racers.AddRange(new Racer[] { new Racer(14, "Niki", "Lauda", "Austria", 25), new Racer(21, "Alain", "Prost", "France", 51)}); var racers2 = new List<Racer>(new Racer[] { new Racer(12, "Jochen", "Rindt", "Austria", 6), new Racer(22, "Ayrton", "Senna", "Brazil", 41) }); } } }
LookupSample
using System; namespace Wrox.ProCSharp.Collections { [Serializable] public class Racer : IComparable<Racer>, IFormattable { public int Id { get; private set; } public string FirstName { get; set; } public string LastName { get; set; } public string Country { get; set; } public int Wins { get; set; } public Racer(int id, string firstName, string lastName, string country = null, int wins = 0) { this.Id = id; this.FirstName = firstName; this.LastName = lastName; this.Country = country; this.Wins = wins; } public override string ToString() { return String.Format("{0} {1}", FirstName, LastName); } public string ToString(string format, IFormatProvider formatProvider) { if (format == null) format = "N"; switch (format.ToUpper()) { case "N": // name return ToString(); case "F": // first name return FirstName; case "L": // last name return LastName; case "W": // Wins return String.Format("{0}, Wins: {1}", ToString(), Wins); case "C": // Country return String.Format("{0}, Country: {1}", ToString(), Country); case "A": // All return String.Format("{0}, {1} Wins: {2}", ToString(), Country, Wins); default: throw new FormatException(String.Format(formatProvider, "Format {0} is not supported", format)); } } public string ToString(string format) { return ToString(format, null); } public int CompareTo(Racer other) { int compare = this.LastName.CompareTo(other.LastName); if (compare == 0) return this.FirstName.CompareTo(other.FirstName); return compare; } } }
using System; using System.Collections.Generic; using System.Linq; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var racers = new List<Racer>(); racers.Add(new Racer(26, "Jacques", "Villeneuve", "Canada", 11)); racers.Add(new Racer(18, "Alan", "Jones", "Australia", 12)); racers.Add(new Racer(11, "Jackie", "Stewart", "United Kingdom", 27)); racers.Add(new Racer(15, "James", "Hunt", "United Kingdom", 10)); racers.Add(new Racer(5, "Jack", "Brabham", "Australia", 14)); var lookupRacers = racers.ToLookup(r => r.Country); foreach (Racer r in lookupRacers["Australia"]) { Console.WriteLine(r); } } } }
ObservableCollectionSample
using System; using System.Collections.ObjectModel; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var data = new ObservableCollection<string>(); data.CollectionChanged += Data_CollectionChanged; data.Add("One"); data.Add("Two"); data.Insert(1, "Three"); data.Remove("One"); } static void Data_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { Console.WriteLine("action: {0}", e.Action.ToString()); if (e.OldItems != null) { Console.WriteLine("starting index for old item(s): {0}", e.OldStartingIndex); Console.WriteLine("old item(s):"); foreach (var item in e.OldItems) { Console.WriteLine(item); } } if (e.NewItems != null) { Console.WriteLine("starting index for new item(s): {0}", e.NewStartingIndex); Console.WriteLine("new item(s): "); foreach (var item in e.NewItems) { Console.WriteLine(item); } } Console.WriteLine(); } } }
PiplelineSample
using System; using System.Collections.Concurrent; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { class Program { static void Main(string[] args) { StartPipeline(); Console.ReadLine(); } private static async void StartPipeline() { var fileNames = new BlockingCollection<string>(); var lines = new BlockingCollection<string>(); var words = new ConcurrentDictionary<string, int>(); var items = new BlockingCollection<Info>(); var coloredItems = new BlockingCollection<Info>(); Task t1 = PipelineStages.ReadFilenamesAsync(@"../../..", fileNames); ConsoleHelper.WriteLine("started stage 1"); Task t2 = PipelineStages.LoadContentAsync(fileNames, lines); ConsoleHelper.WriteLine("started stage 2"); Task t3 = PipelineStages.ProcessContentAsync(lines, words); await Task.WhenAll(t1, t2, t3); ConsoleHelper.WriteLine("stages 1, 2, 3 completed"); Task t4 = PipelineStages.TransferContentAsync(words, items); Task t5 = PipelineStages.AddColorAsync(items, coloredItems); Task t6 = PipelineStages.ShowContentAsync(coloredItems); ConsoleHelper.WriteLine("stages 4, 5, 6 started"); await Task.WhenAll(t4, t5, t6); ConsoleHelper.WriteLine("all stages finished"); } } }
using System.Collections.Concurrent; using System.IO; using System.Linq; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { public static class PipelineStages { public static Task ReadFilenamesAsync(string path, BlockingCollection<string> output) { return Task.Run(() => { foreach (string filename in Directory.EnumerateFiles(path, "*.cs", SearchOption.AllDirectories)) { output.Add(filename); ConsoleHelper.WriteLine(string.Format("stage 1: added {0}", filename)); } output.CompleteAdding(); }); } public static async Task LoadContentAsync(BlockingCollection<string> input, BlockingCollection<string> output) { foreach (var filename in input.GetConsumingEnumerable()) { using (FileStream stream = File.OpenRead(filename)) { var reader = new StreamReader(stream); string line = null; while ((line = await reader.ReadLineAsync()) != null) { output.Add(line); ConsoleHelper.WriteLine(string.Format("stage 2: added {0}", line)); } } } output.CompleteAdding(); } public static Task ProcessContentAsync(BlockingCollection<string> input, ConcurrentDictionary<string, int> output) { return Task.Run(() => { foreach (var line in input.GetConsumingEnumerable()) { string[] words = line.Split(' ', ';', ' ', '{', '}', '(', ')', ':', ',', '"'); foreach (var word in words.Where(w => !string.IsNullOrEmpty(w))) { output.AddOrIncrementValue(word); ConsoleHelper.WriteLine(string.Format("stage 3: added {0}", word)); } } }); } public static Task TransferContentAsync(ConcurrentDictionary<string, int> input, BlockingCollection<Info> output) { return Task.Run(() => { foreach (var word in input.Keys) { int value; if (input.TryGetValue(word, out value)) { var info = new Info { Word = word, Count = value }; output.Add(info); ConsoleHelper.WriteLine(string.Format("stage 4: added {0}", info)); } } output.CompleteAdding(); }); } public static Task AddColorAsync(BlockingCollection<Info> input, BlockingCollection<Info> output) { return Task.Run(() => { foreach (var item in input.GetConsumingEnumerable()) { if (item.Count > 40) { item.Color = "Red"; } else if (item.Count > 20) { item.Color = "Yellow"; } else { item.Color = "Green"; } output.Add(item); ConsoleHelper.WriteLine(string.Format("stage 5: added color {1} to {0}", item, item.Color)); } output.CompleteAdding(); }); } public static Task ShowContentAsync(BlockingCollection<Info> input) { return Task.Run(() => { foreach (var item in input.GetConsumingEnumerable()) { ConsoleHelper.WriteLine(string.Format("stage 6: {0}", item), item.Color); } }); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { public class Info { public string Word { get; set; } public int Count { get; set; } public string Color { get; set; } public override string ToString() { return String.Format("{0} times: {1}", Count, Word); } } }
using System; namespace Wrox.ProCSharp.Collections { public class ConsoleHelper { private static object syncOutput = new object(); public static void WriteLine(string message) { lock (syncOutput) { Console.WriteLine(message); } } public static void WriteLine(string message, string color) { lock (syncOutput) { Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), color); Console.WriteLine(message); Console.ResetColor(); } } } }
using System.Collections.Concurrent; namespace Wrox.ProCSharp.Collections { public static class ConcurrentDictionaryExtension { public static void AddOrIncrementValue(this ConcurrentDictionary<string, int> dict, string key) { bool success = false; while (!success) { int value; if (dict.TryGetValue(key, out value)) { if (dict.TryUpdate(key, value + 1, value)) { success = true; } } else { if (dict.TryAdd(key, 1)) { success = true; } } } } } }
QueueSample
using System; using System.Threading; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var dm = new DocumentManager(); ProcessDocuments.Start(dm); // Create documents and add them to the DocumentManager for (int i = 0; i < 1000; i++) { Document doc = new Document("Doc " + i.ToString(), "content"); dm.AddDocument(doc); Console.WriteLine("Added document {0}", doc.Title); Thread.Sleep(new Random().Next(20)); } Console.ReadKey(); } } }
using System; using System.Threading; using System.Threading.Tasks; namespace Wrox.ProCSharp.Collections { public class ProcessDocuments { public static void Start(DocumentManager dm) { Task.Factory.StartNew(new ProcessDocuments(dm).Run); } protected ProcessDocuments(DocumentManager dm) { if (dm == null) throw new ArgumentNullException("dm"); documentManager = dm; } private DocumentManager documentManager; protected void Run() { while (true) { if (documentManager.IsDocumentAvailable) { Document doc = documentManager.GetDocument(); Console.WriteLine("Processing document {0}", doc.Title); } Thread.Sleep(new Random().Next(20)); } } } }
using System.Collections.Generic; namespace Wrox.ProCSharp.Collections { public class DocumentManager { private readonly Queue<Document> documentQueue = new Queue<Document>(); public void AddDocument(Document doc) { lock (this) { documentQueue.Enqueue(doc); } } public Document GetDocument() { Document doc = null; lock (this) { doc = documentQueue.Dequeue(); } return doc; } public bool IsDocumentAvailable { get { return documentQueue.Count > 0; } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Wrox.ProCSharp.Collections { public class Document { public string Title { get; private set; } public string Content { get; private set; } public Document(string title, string content) { this.Title = title; this.Content = content; } } }
SetSample
using System; using System.Collections.Generic; namespace SetSample { class Program { static void Main() { var companyTeams = new HashSet<string>() { "Ferrari", "McLaren", "Mercedes" }; var traditionalTeams = new HashSet<string>() { "Ferrari", "McLaren" }; var privateTeams = new HashSet<string>() { "Red Bull", "Lotus", "Toro Rosso", "Force India", "Sauber" }; if (privateTeams.Add("Williams")) Console.WriteLine("Williams added"); if (!companyTeams.Add("McLaren")) Console.WriteLine("McLaren was already in this set"); if (traditionalTeams.IsSubsetOf(companyTeams)) { Console.WriteLine("traditionalTeams is subset of companyTeams"); } if (companyTeams.IsSupersetOf(traditionalTeams)) { Console.WriteLine("companyTeams is a superset of traditionalTeams"); } traditionalTeams.Add("Williams"); if (privateTeams.Overlaps(traditionalTeams)) { Console.WriteLine("At least one team is the same with the traditional " + "and private teams"); } var allTeams = new SortedSet<string>(companyTeams); allTeams.UnionWith(privateTeams); allTeams.UnionWith(traditionalTeams); Console.WriteLine(); Console.WriteLine("all teams"); foreach (var team in allTeams) { Console.WriteLine(team); } allTeams.ExceptWith(privateTeams); Console.WriteLine(); Console.WriteLine("no private team left"); foreach (var team in allTeams) { Console.WriteLine(team); } } } }
SortedListSample
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var books = new SortedList<string, string>(); books.Add("Professional WPF Programming", "978–0–470–04180–2"); books.Add("Professional ASP.NET MVC 3", "978–1–1180–7658–3"); books["Beginning Visual C# 2010"] = "978–0–470-50226-6"; books["Professional C# 4 and .NET 4"] = "978–0–470–50225–9"; foreach (KeyValuePair<string, string> book in books) { Console.WriteLine("{0}, {1}", book.Key, book.Value); } foreach (string isbn in books.Values) { Console.WriteLine(isbn); } foreach (string title in books.Keys) { Console.WriteLine(title); } { string isbn; string title = "Professional C# 7.0"; if (!books.TryGetValue(title, out isbn)) { Console.WriteLine("{0} not found", title); } } } } }
StackSample
using System; using System.Collections.Generic; namespace Wrox.ProCSharp.Collections { class Program { static void Main() { var alphabet = new Stack<char>(); alphabet.Push('A'); alphabet.Push('B'); alphabet.Push('C'); Console.Write("First iteration: "); foreach (char item in alphabet) { Console.Write(item); } Console.WriteLine(); Console.Write("Second iteration: "); while (alphabet.Count > 0) { Console.Write(alphabet.Pop()); } Console.WriteLine(); } } }