Refactor to use dispatch_io for tasks, and wait for EOF

Hopefully resolves #139, #135, #161.

/cc @joshaber @keithduncan
Well, to be clear, I don't think we are duplicating the calls anywhere. It was a theoretical concern, but I think we're hewing to the recommendation of the `dispatch_io_close` docs.