| |
 Friday, December 17, 2004
I was looped into a question from a customer today regarding how to best handle exceptions generated by subordinate threads from within the owning thread. They were using threads as a mechanism to do a set of primary tasks in parallel. By primary I mean these aren't just actions that disappear into the background to be executed "at some time in the future," but rather had normal scheduler priority and were responsible for the main workload of the application.
There are plenty of situations where this is a good practice, for example when you need to continually refresh the UI to notify the user of progress. Moreover, if calculations are highly independent and one or more might block and/or if you're on a multi-processor machine, it's often useful to split tasks into many concurrent mini-programs, kick them off, and simply have the parent join on them.
Anyhow, the customer's primary question was around the best way to propagate exceptions back to the owning thread. Truthfully, there isn't a single great way to do this, and it highly depends on your scenario. I did, however, give a simple code snippet of one thought on how to abstract the process of doing this. I figured somebody out there might also find it useful.
The basic idea is to create a thread worker class which encapsulates thread execution and handling of any subsequent errors and calculated values. E.g.
public class ThreadWorker<T>
{
// fields
private T workerReturnValue;
private Exception workerException;
private Thread workerThread;
private ThreadWorkerStart<T> workerStart;
// ctors
public ThreadWorker(ThreadWorkerStart<T> start)
{
workerStart = start;
}
// properties
public T WorkerReturnValue
{
get { return workerReturnValue; }
}
public Exception WorkerException
{
get { return workerException; }
}
// methods
public void Start()
{
workerThread = new Thread(Worker);
workerThread.Start();
}
public T Join()
{
workerThread.Join();
if (workerException != null)
throw new Exception("Worker threw exception", workerException);
return workerReturnValue;
}
private void Worker()
{
try
{
workerReturnValue = workerStart();
}
catch (Exception e)
{
workerException = e;
}
}
}
The Join() method here will either re-throw the exception generated in the ThreadWorkerStart method, or return the calculated value if no exception was generated. This enables you to handle it in the parent thread. Admittedly, the only case you want to do this is when the parent thread can take some corrective action and/or re-run the thread entirely. Most of the time, you want to try and handle exceptions as locally as possible, i.e. in the worker start method itself. However, if the worker thread is unable to do so, letting it leak is sometimes the right thing to do.
For example, this snippetdemonstrates both scenarios:
Random r = new Random();
for (int i = 0; i < 15; i++)
{
ThreadWorker<int> t = new ThreadWorker<int>(delegate()
{
int value = r.Next();
if ((value % 3) == 0)
throw new Exception("Uh oh, something bad happened");
else
return value;
});
t.Start();
try
{
Console.WriteLine("{0}. Worker output: {1}", i, t.Join());
}
catch (Exception ex)
{
Console.WriteLine("{0}. Worker exception: {1}", i, ex.InnerException.ToString());
}
}
Here, we generate, execute, and join on 15 threads, each of which will throw an exception should a random number be divisible by 3. Our code will print out either the computed value or the exception depending on whether the worker method throws an exception or not.
Anybody who seriously enjoys a great cup of loose tea should check out Upton's Gu Zhu Zi Sun.
Very thick vegetal quality with a great flavor and amazing texture. It reminds me of some of the older Tie Kwan Yin monkey picked oolongs from a couple years ago, with a very buttery, smooth texture. Unlike many high end greens, the flavor notes are very pronounced. I'm about to experiment to see if it can take multiple infusions, but if not I fear I'm going to have to buy some more. At over $25 per 120 grams, this puppy's up there in price.
What an addict will do for a fix. ;)
 Sunday, December 12, 2004
Thanks for all of the answers to the quiz. I appreciate the involvement, and most of the feedback was exactly the kind of thing we're looking for.
Quiz Answers
Before jumping into this in too much detail, I'll first go ahead and answer the set of answers from the first post. Several answers to the post were correct, while others were mostly correct. I loved the comment “Obviously its a confusing API. [snip] Keep it simple, no?” I couldn't agree more. :) Anyhow, on to the answers!
- What does invoking Close() on an open Stream do?
The implementation should free any large allocations of memory (flushing of buffers, for example) and release any unmanaged resources. I'm speaking in terms of the contract of this method, but obviously FileStream and other Stream-derived types we ship implement this contract correctly. There’s no guarantee that the object will be useable after calling this.
- What does invoking Dispose() on an open Stream do?
It calls Close().
- Should you call both at some point in a Stream's lifecycle?
No! Call one or the other, they do the same exact thing.
- If not, why?
Calling both is wasteful as they do the same thing. They are both resilient to multiple calls, so nothing terrible will happen if you do end up calling them both.
- Can you call only one without having to call the other?
Yep. In fact, you should.
- Is it weird that there is both a Close() and Dispose() on a single type, or does that seem natural? Based on your understanding of the pattern, do you think we should continue to use it, or is there a better one?
I think it is certainly confusing, and that in the future we can work on making this clearer. My philosophy—outlined further below—is that hiding Dispose() as an explicit interface implementation has resulted in a lot of confusion around user perception of disposability. If a public Dispose() method suddenly showed up on FileStream, for example, people would likely not know what to do (and probably end up calling both).
A Bit of History
We have had guidelines around Dispose() for quite a long time, and it turns out that most people developing classes for the Framework actually follow them! The guidelines suggest that, should a more domain-appropriate name for a Dispose()-like activity be present (e.g. closing a stream, database connection, etc.), a class should explicitly implement IDisposable.Dispose(), and create the more domain-specific method to cleanup resources to be directly called by developers. In such a situation, both Dispose() and this other method, usually Close(), should do the same thing.
The only reasoning I've heard for originally creating this redundancy is to play nicely with C#'s using statement (or other IDisposable-based mechanisms). It isn't expected that people would ever manually call Dispose(), hence the reason for effectively hiding it. For example,
using (Stream s = //...)
{
//...
}
...or
Stream s = //...
try
{
//...
}
finally
{
s.Close();
}
...are both expected coding patterns. But,
Stream s = //...
try
{
//...
}
finally
{
((IDisposable)s).Dispose();
}
...is not. If Dispose() were public, the cast wouldn’t be necessary in the last example, but admittedly many people would probably write code like this:
Stream s = //...
try
{
//...
}
finally
{
s.Close();
s.Dispose();
}
We’re already making it easy to write the following code in today’s world:
using (Stream s = //...)
{
try
{
//...
}
finally
{
s.Close();
}
}
...which incidentally is probably a better pattern if you did have to call both Close() and Dispose(), just in case Close() had decided to throw an exception.
The Dispose(bool) Pattern
For some situations, such as with FileStream, for example, we've further refined the pattern to use Dispose(bool disposing). This is necessary in situations where cleanup logic differs depending on whether you are finalizing or explicitly disposing of an object, and helps to prevent duplication of cleanup code in multiple methods. Unfortunately, Dispose(bool) should always be a protected method, so without any support for protected interfaces, it's really just a documented pattern and not captured as an interface contract anywhere. Nonetheless, it's very widely used in the Framework.
The idea is that all of the logic for cleanup goes into Dispose(bool), and both the finalizer and Dispose() method call into it passing different bool values. A finalizer calling Dispose(bool) passes in false, while Dispose() passes in true as the argument. The method then uses this information to sort of bifurcate its logic into stuff appropriate to do during finalization and other things which are appropriate in both finalize and dispose cases. The former is a subset due to the strict requirements around what you can and cannot do/touch in a finalizer along with the fact that you don’t need to suppress finalization if you are already being finalized. This pattern will typically look something like this:
class MyType : IDisposable
{
~MyType()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
// shared cleanup logic
if (disposing)
{
// dispose-specific logic
GC.SuppressFinalize(this);
}
}
}
Base classes will then override Dispose(bool) to customize behavior, making sure to call base.Dispose(disposing) at the very end of the override. The least derived type's implementation makes a virtual call to Dispose(bool), so it's never necessary for a further derived type to change this definition. Interestingly, the only dispose-specific logic that typically needs to be captured is a call to GC.SuppressFinalize(this).
So what happens if we throw a Close() method into the mix? Well, the Close() method itself just does the same thing as Dispose() -- that, they both make a call to Dispose(true). But, the pattern also goes on to say that you should explicitly implement Dispose(), hiding it from the public surface of the class. (Note this is the case even in situations where the Dispose(bool) pattern isn’t being used. So, if you just have a Close() and Dispose() method, Dispose() should be explicitly implemented.) So our class changes to the following:
class MyType : IDisposable
{
~MyType()
{
Dispose(false);
}
public void Close()
{
Dispose(true);
}
void IDisposable.Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
// shared cleanup logic
if (disposing)
{
// dispose-specific logic
GC.SuppressFinalize(this);
}
}
}
To further illustrate the way methods relate to and delegate to each other under this pattern, consider this diagram:

Regardless of the complexity, notice what a developer would see in IntelliSense: one method called Close(). It’s easy to lose track of this fact when discussing all of these implementation details.
Some Philosophy
It turns out that I disagree with the hiding of Dispose() in such circumstances. Arguably, somebody won’t forget to Close() a FileStream, but anything that holds on to precious resources should scream out that it needs to be cleaned up and I believe that a Dispose() method is a consistent and clear way to do just that. Moreover, the contract of Dispose() and Close() are slightly different to me: Dispose() is the equivalent to a deterministic destructor, while Close() is a semantically-meaningful operation for a given class. For example, FileStream.Dispose() means “I am done with this stream, clean up any expensive resources to hold on to and make it unusable from this point on;” on the other hand, FileStream.Close() means precisely “Flush the buffer and close the file.” (You could argue that flushing should be an explicit action, too, but that’s a different topic.) Yes disposing a FileStream will end up closing it, but this is a subset of the range of actions Dispose() could take. That they are implemented in the same fashion is… well… an implementation detail, and I don’t particularly see the need to confuse people by continuing to pretend they are the same exact thing.
I firmly believe that hiding Dispose() has already damaged our ability to educate users about disposability. For example, we can now never make Close() do something different than Dispose() on FileStream. There are plenty of customers out there who have been told that Close() is equivalent and have written code that makes this assumption. Changing the semantics at this point would break existing code. You could also convincingly argue that because of this very point, we should never make Close() and Dispose() differ under any circumstance… But I digress. :)
Things are further complicated by our use of “re-openable” resources, such as System.Diagnostics.Process (you can Start(), Close(), Start(), Close(), … where each Close() effectively disposes of the instance and each Start() recreates it) and System.Data.SqlClient.SqlConnection (you can Open(), Close(), Open(), Close(), … where each Close() is almost identical to Dispose() with some minor differences).
Future Direction
Our pattern as implemented has caused a bit of confusion and problems recently internally, so I am wondering if anybody out there has also run into problems with it. If so, speak up! We’d love to hear feedback.
One very real issue is that if you’re going to subclass Stream, there’s no way to chain the base class Dispose() method since it’s explicitly implemented (which turns out to be a private method in the metadata). To do it right, you just need to know that Dispose() calls Close() (a pretty intimate piece of implementation trivia). Further, in the Dispose(bool) cases, you need to ignore Dispose() and just write a Dispose(bool) implementation that makes sure to chain the base class method. Unfortunately, you just have to take it on its face that the base class is implemented correctly and that your re-implemented dispose method will end up being called at precisely the right time. Moreover, the fact that the pattern is not captured as an interface of any sort makes such hierarchies feel a bit brittle after several levels of inheritance. The C# compiler auto-chains finalizers, a very nice convenience; it’d also be nice if it knew the right thing to do with Dispose() implementations, too.
We had recently considered changing this pattern and the associated Framework classes to have public Dispose() methods, but it is fraught with problems. Not only would these very familiar classes now have two public cleanup methods (Dispose() and Close(), for example), but it turns out that encouraging derived classes to override Dispose() is a bad idea with the current pattern. It relies on base classes overriding Dispose(bool) and leaving Dispose() alone.
There are certainly alternate designs to consider, and lots of room for support by both the C# compiler and the CLR in deterministic resource cleanup. These guys have done a great job pioneering this space with their forthcoming release of C++/CLI, which has both automatic deterministic finalization and generation and chaining of Dispose() methods (what they refer to destructors… yet another thing we as C#-ers need to work on: a finalizer is not a destructor; Dispose() is much closer to what has been for a long time referred to as a destructor, and we’d be better of if we got our terminology straight). I encourage you to check it out.
I’ll have plenty more information coming in the following weeks, including an update to our existing Design Guidelines for implementing finalizers and Dispose() methods… Stay tuned.
Appendix: A Tidbit on Explicitly Implemented Interfaces
Interestingly, explicitly implemented interface methods have the drawback of not being able to bind to a precise version in the hierarchy anyways (even though they are non-virtual). Calling a method through an interface map will always end up as a virtual call to the most-derived implementation. Consider this example:
class A : IDisposable
{
void IDisposable.Dispose()
{
Console.WriteLine("A.Dispose()");
}
internal void Close()
{
((IDisposable)this).Dispose();
}
}
class B : A, IDisposable
{
void IDisposable.Dispose()
{
Console.WriteLine("B.Dispose()");
}
}
With these classes, calling:
B b = new B();
b.Close();
...will end up in a virtual dispatch to the Dispose() implementation on class B. This shouldn’t be surprising, but it means that you can never really be sure that you’re the last interface implementation in a hierarchy which can be troublesome in situations like the C# using statement. For example,
using (B b = new B())
{
}
...will likewise end up as a call to B’s version of Dispose() although A might not be designed to deterministically release its resources correctly should its Dispose() behavior be overridden.
 Friday, December 10, 2004
So you may or may not have noticed that System.IO.Stream both has a Close() method and implements IDisposable, meaning it has a Dispose() method, too. (Note: it's explicitly implemented, meaning that to access it you'll need to use an IDisposable typed reference in C#, e.g. as in ((IDisposable)myStream).Dispose().) Stream is an abstract base class, the most common derivitive being FileStream.
Without consulting Reflector, ;) can you answer these questions?
- What does invoking Close() on an open Stream do?
- What does invoking Dispose() on an open Stream do?
- Should you call both at some point in a Stream's lifecycle?
- If so, when and in what order?
- If not, why?
- Can you call only one without having to call the other?
- Is it weird that there is both a Close() and Dispose() on a single type, or does that seem natural? Based on your understanding of the pattern, do you think we should continue to use it, or is there a better one?
I have a much lengthier post that I'm writing up regarding an internal design debate we're currently involved in - responses will help to shape both the post and the debate. :)
 Tuesday, December 07, 2004
I made a couple small improvements to my brain dump from last night. I added a few continuation-ish constructor and Wait(...) overloads that take a consequent and alternate Action<T> (a new delegate type in Whidbey). Action<T> is just a void(T) function that executes a set of statements (with no return value). If the guarded condition is met, the wait class just executed your consequent from within a locked context; if not, it will execute the alternate from the same context.
For example, here is the new definition of GuardedWait<T> (sorry--it's gotten a bit lengthy):
public class GuardedWait<T>
{
// fields
private Predicate<T> predicate;
private Action<T> consequent;
private Action<T> alternate;
// ctors
public GuardedWait(Predicate<T> p) : this(p, null)
{
}
public GuardedWait(Predicate<T> p, Action<T> c) : this(p, c, null)
{
}
public GuardedWait(Predicate<T> p, Action<T> c, Action<T> a)
{
this.predicate = p;
this.consequent = c;
this.alternate = a;
}
// methods
public bool IsTrue(T on)
{
return predicate(on);
}
private bool WaitImpl(T on, int millisecondsTimeout)
{
int counter = millisecondsTimeout;
while (true)
{
long beginTick = DateTime.Now.Ticks;
if (!Monitor.Wait(on, counter))
return false;
if (IsTrue(on))
return true;
counter -= (int)new TimeSpan(
DateTime.Now.Ticks - beginTick).TotalMilliseconds;
if (counter <= 0)
return false;
}
}
public bool Wait(T on)
{
return Wait(on, -1);
}
public bool Wait(T on, int millisecondsTimeout)
{
return Wait(on, millisecondsTimeout, consequent, alternate);
}
public bool Wait(T on, Action<T> consequent)
{
return Wait(on, consequent, null);
}
public bool Wait(T on, int millisecondsTimeout, Action<T> consequent)
{
return Wait(on, millisecondsTimeout, consequent, null);
}
public bool Wait(T on, Action<T> consequent, Action<T> alternate)
{
return Wait(on, -1, consequent, alternate);
}
public bool Wait(T on, int millisecondsTimeout, Action<T> consequent, Action<T> alternate)
{
lock (on)
{
if (WaitImpl(on, millisecondsTimeout))
{
if (consequent != null)
consequent(on);
return true;
}
else
{
if (alternate != null)
alternate(on);
return false;
}
}
}
}
Fairly boring boilerplate, but it means we can now write simplified consumer code, such as:
static void Consumer(Queue<int> q, int count)
{
Thread t = new Thread(delegate()
{
GuardedWait<Queue<int>> wait = ProduceQueueConsumer<int>(count, 0.5f);
while (true)
{
wait.Wait(q);
}
});
t.IsBackground = true;
t.Start();
}
Notice we no longer have to worry about locking ourselves and in fact can even abstract away the process of consumption. In this case, we have implemented a somewhat reusable static factory method, ProduceQueueConsumer:
static GuardedWait<Queue<T>> ProduceQueueConsumer<T>(int threshold, float fillFactor)
{
int target = (int)(fillFactor * threshold);
return new GuardedWait<Queue<T>>(
delegate(Queue<T> tq) { return tq.Count >= threshold; },
delegate(Queue<T> tq) {
while (tq.Count >= target)
{
T consumed = tq.Dequeue();
Console.WriteLine("Consumed {0} [{1}]", consumed, tq.Count);
}
});
}
This method just takes an absolute threshold, a fill factor (between 0.0f and 1.0f) that represents the percent of the threshold to reduce the queue to when it reaches the threshold. Fairly esoteric I suppose, but I think it's cool. :)
 Monday, December 06, 2004
A guarded wait is a locking primitive which enters an object's monitor and performs some processing once a certain predicate condition arises. You could imagine a buffer which refills itself once its contents have been consumed, a consumer which empties a buffer once it reaches a certain capacity, and so on.
Using the new Predicate<T> class in the Framework 2.0, the following is a pretty straightforward implementation of such a construct:
public class GuardedWait<T>
{
private Predicate<T> predicate;
public GuardedWait(Predicate<T> p)
{
predicate = p;
}
public bool IsTrue(T on)
{
return predicate(on);
}
public bool Wait(T on)
{
return Wait(on, -1);
}
public bool Wait(T on, int millisecondsTimeout)
{
int counter = millisecondsTimeout;
while (true)
{
long beginTick = DateTime.Now.Ticks;
lock (on)
{
if (!Monitor.Wait(on, counter))
return false;
if (IsTrue(on))
return true;
}
counter -= (int)new TimeSpan(
DateTime.Now.Ticks - beginTick).TotalMilliseconds;
if (counter <= 0)
return false;
}
}
}
As you can see, the public contract is very simple and familiar. It has a constructor which takes a predicate operation. This is the condition to guard on, that is, when waiting this is the condition that must be true for the lock to be considered successful. Then we have two simple bool Wait(...) operations which are very much like the Monitor.Wait(...) methods. This relies on the use of Monitor.Notify*() in order to wake up the wait class to check for its predicate condition.
Lastly, consider a simple example of its use. In this snippet, we share a queue between a producer and a consumer. Assume there is a contract in place that the consumer never lets the queue get beyond a certain threshold, and will deplete the buffer to half of its capacity each time it reaches such a threshold. This code effectively accomplishes this:
class GuardedWaitTest
{
public static void Main(string[] args)
{
Queue<int> q = new Queue<int>();
Producer(q);
Consumer(q, 150);
Thread.Sleep(5000);
}
static void Producer(Queue<int> q)
{
Thread t = new Thread(delegate()
{
Random r = new Random();
while (true)
{
lock (q)
{
int next = r.Next();
q.Enqueue(next);
Console.WriteLine("Produced {0} [{1}]", next, q.Count);
Monitor.Pulse(q);
}
}
});
t.IsBackground = true;
t.Start();
}
static void Consumer(Queue<int> q, int count)
{
Thread t = new Thread(delegate()
{
GuardedWait<Queue<int>> wait = new GuardedWait<Queue<int>>(delegate(Queue<int> tq)
{
return tq.Count >= count;
});
while (true)
{
lock (q)
{
if (wait.Wait(q))
{
while (q.Count >= (count / 2))
{
int consumed = q.Dequeue();
Console.WriteLine("Consumed {0} [{1}]", consumed, q.Count);
}
}
}
}
});
t.IsBackground = true;
t.Start();
}
}
This code is relatively straightforward, albeit verbose because I am trying to carefully orchestrate the interaction between threads. Producer simply generates random numbers and Enqueue()s them into the shared Queue. Consumer uses the GuardedWait<T> class to “wake up” when (in this case) 150 items have been placed into the queue. It then consumed half of these, and relinquishes the lock back to the Producer. Obviously a simple example, but it should give you a good idea of when such a construct might be useful.
 Wednesday, December 01, 2004
 Tuesday, November 30, 2004
I'm several chapters through my book. Well, rough draft chapters that is--I suppose there's a subtle difference. ;) And I have a question that hopefully at least one person out there can provide feedback on.
As I am writing, I'm constantly battling with the whole “know your user” dillemma. This fundamental tenet applies to building products, designing APIs, and writing books, too. If my book is under or over the head of my target audience, well... folks likely won't read it! At this point, it's hard to pinpoint exactly who my readers will be. My envisioned persona at this point is an IT software professional who either has a couple years of experience or a CS degree. This person enjoys reading about technologies, but at the same time has a job to do and will be using the book as a crucial tool to enable them in doing it.
Seeing as I've never explicitly said what the book is, let me do that: roughly, it is a whirlwind tour of the CLR and .NET Framework, with a focus on 2.0 stuff. There are several similar works out there already, so I'm trying to differentiate myself with a more technical, geekish edge, and great coverage of the new 2.0 features.
So here comes my constant internal debate. How much computer science-ish stuff should it contain? I mean, there's a certain level needed to understand some concepts, but many could just as easily be glossed over. Moreover, if folks need to learn about hardcore CS stuff, well... there are plenty of classic texts out there already. Take type systems, for example. I could just say: hey, there are these things called types, of which there are two categories... value and reference types. The differences are X, and you use them by doing Y. And so on. Or, I could take a step back, and briefly discuss the design decisions made when choosing strong vs. latent typing, a good mixture of static and dynamic type checking, and so on. I could easily spend 1/5 of the entire Type System chapter on this alone. But I fear that could be a mistake.
I suppose there is a subtle difference... however, I do know that many people out there just want to “see the code” when they buy a book. Not read through a whole bunch of geeky expositions.
Any opinions would be awesome! Thanks...
 Saturday, November 27, 2004
Streams are a construct which go hand in hand with Thunks. They enable lazy loading and calculation of algorithms, and can be particularly interesting due to the ease with which they compose. The examples I provide below make heavy use of new C# 2.0 features, such as anonymous delegates and iterators. Some will notice my undeniable influence by the Wizard book in the concepts presented here.
First, consider a new type Stream<T>:
public class Stream<T> : IEnumerable<T>
{
//fields
private List<T> memory = new List<T>();
private Evaluator evaluator;
private int count;
public delegate Nullable<T> Evaluator();
//ctors
public Stream(Evaluator evaluator) : this(evaluator, -1)
{
}
public Stream(Evaluator evaluator, int count)
{
this.evaluator = evaluator;
this.count = count;
}
//properties
public int Capacity
{
get
{
if (count == -1)
return int.MaxValue;
return count;
}
}
public int Count
{
get
{
if (count == -1)
return MemoryCount;
return count;
}
}
public int MemoryCount
{
get
{
return memory.Count;
}
}
public T this[int index]
{
get
{
if (memory.Count <= index)
for (int i = memory.Count; i <= index; i++)
Memoize();
return memory[index];
}
}
//methods
public IEnumerator<T> GetEnumerator()
{
int i = 0;
while (i <= Capacity)
{
yield return this[i];
i++;
}
}
private void Memoize()
{
Nullable<T> n = evaluator();
if (!n.HasValue)
throw new ArgumentOutOfRangeException("No value for the specified index");
memory.Add(n.Value);
}
}
This takes an Evaluator delegate, a no-args method which returns an instance of Nullable<T>. I have chosen to implement a memoized stream, to make re-accessing previously computed indexes possible. This simply means that calculated values are "remembered" once they have been generated. My implementation actually wouldn't work without memoization since it uses state variables to track its computation. This will lazily load up to the index which is requested.
This can be used, for example, to calculate numbers in the Fibonacci series.
Stream<long> CreateFibStream()
{
long i1 = 1;
long i2 = 1;
return new Stream<long>(delegate
{
long t = i1;
i1 = i2;
i2 = t + i2;
return t * 4;
});
}
This code can be used to calculate the first 10 numbers in the Fibonacci series as follows:
Stream<long> fib = CreateFibStream();
for (int i = 0; i < 10; i++)
Console.WriteLine(fib[i]);
The output of this program is as follows:
1
1
2
3
5
8
13
21
34
55
Notice that, because of the indexer, you can request, say, the 15th Fibonacci number directly:
Console.WriteLine(fib[14]);
This prints out the number 610.
Because streams are easily composable, I've easily created a few standard factory methods which construct an augmented stream. These simply wrap an existing stream and lazily change the output as it is requested. For example, Amplifier<T> will amplify the numbers generated by a target stream by a constant number as they are retrieved.
public static Stream<U> Transform<T, U>(Converter<T, U> c, Stream<T> s)
{
IEnumerator<T> e = s.GetEnumerator();
return new Stream<U>(delegate
{
e.MoveNext();
return c(e.Current);
});
}
public static Stream<double> Amplifier<T>(Stream<T> s, double y)
{
return Transform<T, double>(new Converter<T, double>(delegate(T x) {
return Convert.ToDouble(x) * y; }),
s);
}
For instance, we can use this in calculation of pi as follows:
Stream<double> CreatePiStream()
{
double n = 1.0;
double last = 0.0;
bool add = true;
return StreamFactory.Amplifier<double>(
new Stream<double>(delegate
{
double d = 1 / n;
if (!add)
d *= -1;
add = !add;
last += d;
n += 2;
return last;
}),
4.0);
}
The first 15 iterations of this produce these numbers:
4 2.66666666666667 3.46666666666667 2.8952380952381 3.33968253968254 2.97604617604618 3.28373848373848 3.01707181707182 3.25236593471888 3.0418396189294 3.23231580940559 3.05840276592733 3.21840276592733 3.07025461777919 3.20818565226194
The 100th number is 3.13159290355855. Notice how slowly this method converges towards the real pi.
Another useful standard augmentation is a so-called Euler transform, which acts as an accelerator causing our pi generator to converge more rapidly. The technique used is to calculate any number S as Sn+1 - ((Sn+1 - Sn)2)/(Sn-1 - 2Sn + Sn+1), where n is an index into the sequence of values.
public static Stream<double> EulerTransform<T>(Stream<T> s)
{
int i = 0;
return new Stream<double>(delegate
{
double s0 = Convert.ToDouble(s[i++]);
double s1 = Convert.ToDouble(s[i++]);
double s2 = Convert.ToDouble(s[i++]);
return s2 - (Math.Pow(s2 - s1, 2) / (s0 - (2 * s1) + s2));
});
}
For example, consider this method of accelerating our generation of pi:
Stream<double> pis = StreamFactory.EulerTransform<double>(CreatePiStream());
for (int i = 0; i < 15; i++)
Console.WriteLine(pis[i]);
The output of the first 15 iterations is as follows - notice that it converges towards pi much more rapidly than the previous example:
3.16666666666667 3.13968253968254 3.14207181707182 3.1414067184965 3.14168318920776 3.14154198599778 3.14162380666784 3.14157215448297 3.14160685134755 3.14158241824775 3.14160027369869 3.14158682862116 3.14159720571187 3.14158902894078 3.14159558652131
And, lastly, the 100th number using the Euler accelerated sequence is 3.14159264423745. Interestingly, we can do accelerate an accelerated sequence, and so on, for example as in:
Stream<double> pis = StreamFactory.EulerTransform<double>(
StreamFactory.EulerTransform<double>(
StreamFactory.EulerTransform<double>(
CreatePiStream())));
Indexing into the 100th number here is 3.14159265358979, the same exact number returned by the Math.PI constant.
 Thursday, November 25, 2004
Those who haven't heard of or played around on TopCoder don't know what they're missing.
For example, I just spent the last 45 minutes working on a set of three different algorithmic problems. Each rises in difficulty, and you are awarded points based factors such as the amount of time it takes you to finish. There's a set of test suites that validate your solution after you finish. You can program in essentially whatever language you feel most comfortable in (C#, Java, VB, C++), and a practice room is available if you need some time to get used to things. “Real” competitions are scheduled regularly.
The hardest of these three exercises I just completed was an English to “Taglish” translator. It essentially just does some verb conjugation and other hackery to transform an input string. My solution can be seen here. I encourage you to give it a try before looking. It's in the SRM 220 DIV 2 set of problems.
What's amazing is how elegant and ugly solutions to the same problem can be. (The code I have shared is certainly in the latter category! ;) ) Once you submit your answer, you can take a look at what other folks submitted.
|
|
Me
Joe  is an architect and developer on a systems incubation project at Microsoft.
Recent
Search
Browse
Disclaimer:
The content of this site are my own personal opinions and do
not represent my employer's view in anyway.
© 2013, Joe Duffy
|
|