Skip to content

Instantly share code, notes, and snippets.

@danesparza
Created July 22, 2015 15:03
Show Gist options
  • Save danesparza/d666eabf44887607ab6a to your computer and use it in GitHub Desktop.
Save danesparza/d666eabf44887607ab6a to your computer and use it in GitHub Desktop.
TPL data flow test
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