diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+0.7.2.1
+-------
+- Asynchronous cancellation now works on Windows (issue #8)
+
 0.7.2.0
 -------
 - contraproduce, contraencoded, Splitter, splitIntoLines, nest    
diff --git a/process-streaming.cabal b/process-streaming.cabal
--- a/process-streaming.cabal
+++ b/process-streaming.cabal
@@ -1,5 +1,5 @@
 name:          process-streaming
-version:       0.7.2.0
+version:       0.7.2.1
 license:       BSD3
 license-file:  LICENSE
 data-files:    
@@ -44,7 +44,7 @@
         void >= 0.6 && < 1.0,
         containers >= 0.4,
         semigroups >= 0.15 && < 0.20,
-        conceit >= 0.2.2.1 && < 0.3.0.0,
+        conceit >= 0.3.1.0 && < 0.4.0.0,
         contravariant >= 1.2,
         foldl >= 1.0.7
 
diff --git a/src/System/Process/Streaming.hs b/src/System/Process/Streaming.hs
--- a/src/System/Process/Streaming.hs
+++ b/src/System/Process/Streaming.hs
@@ -111,7 +111,6 @@
         , T.decodeIso8859_1
     ) where
 
-import qualified Data.ByteString as BS
 import qualified Data.ByteString.Lazy as BL
 import Data.Functor.Contravariant
 import Data.Functor.Contravariant.Divisible
@@ -232,18 +231,27 @@
             throwIO (userError "stdin/stdout/stderr handle unwantedly null")
             `finally`
             terminateCarefully phandle 
-        Just t -> 
-            let (action,cleanup) = allocator t in
+        Just t -> do
+            latch <- newEmptyMVar
+            let (action,cleanup) = allocator t
+                innerRace = _runConceit $
+                    (_Conceit (takeMVar latch >> terminateOnError phandle action))
+                    <|>   
+                    (_Conceit (onException (putMVar latch () >> _runConceit Control.Applicative.empty) 
+                                           (terminateCarefully phandle))) 
             -- Handles must be closed *after* terminating the process, because a close
             -- operation may block if the external process has unflushed bytes in the stream.
-            (restore (terminateOnError phandle action) `onException` terminateCarefully phandle) `finally` cleanup 
+            (restore innerRace `onException` terminateCarefully phandle) `finally` cleanup 
 
 
+
 terminateCarefully :: ProcessHandle -> IO ()
 terminateCarefully pHandle = do
     mExitCode <- getProcessExitCode pHandle   
     case mExitCode of 
-        Nothing -> terminateProcess pHandle  
+        Nothing -> catch 
+            (terminateProcess pHandle) 
+            (\(_::IOException) -> return ())
         Just _ -> return ()
 
 terminateOnError :: ProcessHandle 
diff --git a/src/System/Process/Streaming/Extended.hs b/src/System/Process/Streaming/Extended.hs
--- a/src/System/Process/Streaming/Extended.hs
+++ b/src/System/Process/Streaming/Extended.hs
@@ -25,19 +25,12 @@
     ) where
 
 import Data.Text 
-import Data.Void
-import Data.Monoid
 import Control.Applicative
 import Control.Exception
 import Control.Concurrent.Conceit
-import Control.Monad
-import Control.Monad.Trans.Except
 import Pipes.ByteString
 import System.IO
 
-import Pipes
-import Pipes.Core
-import qualified Pipes.Prelude as P
 import System.Process.Streaming
 import System.Process.Streaming.Internal
 
