Created
July 22, 2015 15:03
-
-
Save danesparza/d666eabf44887607ab6a to your computer and use it in GitHub Desktop.
TPL data flow test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Net; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Threading.Tasks.Dataflow; | |
namespace TPLDataflowTest | |
{ | |
/// <summary> | |
/// Shamelessly taken from http://msdn.microsoft.com/en-us/library/hh228604(v=vs.110).aspx | |
/// </summary> | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Our pipeline members: | |
// Download the requested resource as a string: | |
var downloadString = new TransformBlock<string, string>(uri => | |
{ | |
// Indicate our progress to the console: | |
Console.WriteLine("Downloading '{0}'", uri); | |
// Download the string and return it: | |
return new WebClient().DownloadString(uri); | |
}); | |
// Seperate the specified text into an array of words | |
var createWordList = new TransformBlock<string, string[]>(text => | |
{ | |
Console.WriteLine("Creating word list from text that is {0} chars long", text.Length); | |
// Remove common punctuation by replacing all non-letter chars with a space character | |
char[] tokens = text.ToArray(); | |
for(int i = 0; i < tokens.Length; i++) | |
{ | |
if(!char.IsLetter(tokens[i])) | |
tokens[i] = ' '; | |
} | |
text = new string(tokens); | |
// Seperate into an array of words | |
return text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); | |
}); | |
// Remove short words, orders the resulting words alphabetically and remove duplicates | |
var filterWordList = new TransformBlock<string[], string[]>(words => | |
{ | |
Console.WriteLine("Filtering word list..."); | |
return words.Where(word => word.Length > 3).OrderBy(word => word).Distinct().ToArray(); | |
}); | |
// Find the palindromes of words that also exist in the collection | |
var findPalindromes = new TransformManyBlock<string[], string>(words => | |
{ | |
Console.WriteLine("Finding palindromes"); | |
var palindromes = new ConcurrentQueue<string>(); | |
Parallel.ForEach(words, word => | |
{ | |
// Reverse the word | |
string reverse = new string(word.Reverse().ToArray()); | |
if(Array.BinarySearch<string>(words, reverse) >= 0 && word != reverse) | |
{ | |
palindromes.Enqueue(word); | |
} | |
}); | |
return palindromes; | |
}); | |
// Print the palindrome | |
var printPalindrome = new ActionBlock<string>(palindrome => | |
{ | |
Console.WriteLine("Found palindrome {0}/{1}", palindrome, new string(palindrome.Reverse().ToArray())); | |
}); | |
// Form the pipeline | |
downloadString.LinkTo(createWordList); | |
createWordList.LinkTo(filterWordList); | |
filterWordList.LinkTo(findPalindromes); | |
findPalindromes.LinkTo(printPalindrome); | |
// Create the completion tasks: | |
downloadString.Completion.ContinueWith(t => | |
{ | |
if(t.IsFaulted) | |
((IDataflowBlock)createWordList).Fault(t.Exception); | |
else | |
createWordList.Complete(); | |
}); | |
createWordList.Completion.ContinueWith(t => | |
{ | |
if(t.IsFaulted) | |
((IDataflowBlock)filterWordList).Fault(t.Exception); | |
else | |
filterWordList.Complete(); | |
}); | |
filterWordList.Completion.ContinueWith(t => | |
{ | |
if(t.IsFaulted) | |
((IDataflowBlock)findPalindromes).Fault(t.Exception); | |
else | |
findPalindromes.Complete(); | |
}); | |
findPalindromes.Completion.ContinueWith(t => | |
{ | |
if(t.IsFaulted) | |
((IDataflowBlock)printPalindrome).Fault(t.Exception); | |
else | |
printPalindrome.Complete(); | |
}); | |
// Process "The Iliad of Homer" by Homer. | |
downloadString.Post("http://www.gutenberg.org/files/6130/6130-0.txt"); | |
// Mark the head of the pipeline as complete. The continuation tasks | |
// propagate completion through the pipeline as each part of the | |
// pipeline finishes. | |
downloadString.Complete(); | |
// Wait for the last block in the pipeline to process all messages. | |
printPalindrome.Completion.Wait(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment