diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,13 @@
 Changes
 =======
 
+Version 1.2.3
+-------------
+
+* Expose `computeStatistics` from `Test.Tasty.Ingredients.ConsoleReporter`.
+* Ensure that `finally` and `bracket` work as expected inside tests
+  when the test suite is interrupted by Ctrl-C.
+
 Version 1.2.2
 -------------
 
diff --git a/Test/Tasty/Ingredients/ConsoleReporter.hs b/Test/Tasty/Ingredients/ConsoleReporter.hs
--- a/Test/Tasty/Ingredients/ConsoleReporter.hs
+++ b/Test/Tasty/Ingredients/ConsoleReporter.hs
@@ -15,6 +15,7 @@
   , useColor
   -- ** Test failure statistics
   , Statistics(..)
+  , computeStatistics
   , printStatistics
   , printStatisticsNoTime
   -- ** Outputting results
@@ -287,6 +288,9 @@
   (<>) = mappend
 #endif
 
+-- | @computeStatistics@ computes a summary 'Statistics' for
+-- a given state of the 'StatusMap'.
+-- Useful in combination with @printStatistics@
 computeStatistics :: StatusMap -> IO Statistics
 computeStatistics = getApp . foldMap (\var -> Ap $
   (\r -> Statistics 1 (if resultSuccessful r then 0 else 1))
diff --git a/Test/Tasty/Parallel.hs b/Test/Tasty/Parallel.hs
--- a/Test/Tasty/Parallel.hs
+++ b/Test/Tasty/Parallel.hs
@@ -4,6 +4,7 @@
 
 import Control.Monad
 import Control.Concurrent
+import Control.Concurrent.Async
 import Control.Concurrent.STM
 import Foreign.StablePtr
 
@@ -52,9 +53,19 @@
 
   actionsVar <- atomically $ newTMVar actions
 
-  pids <- replicateM nthreads (forkIO $ work actionsVar)
+  pids <- replicateM nthreads (async $ work actionsVar)
 
-  return $ mapM_ killThread pids
+  return $ do
+    -- Tell worker threads there is no more work after their current task.
+    -- 'cancel' below by itself is not sufficient because if an exception
+    -- is thrown in the middle of a test, the worker thread simply marks
+    -- the test as failed and moves on to their next task. We also need to
+    -- make it clear that there are no further tasks.
+    _ <- atomically $ swapTMVar actionsVar []
+    -- Cancel all the current tasks, waiting for workers to clean up.
+    -- The waiting part is important (see #249), that's why we use cancel
+    -- instead of killThread.
+    mapM_ cancel pids
 
 work :: TMVar [Action] -> IO ()
 work actionsVar = go
@@ -63,8 +74,10 @@
       join . atomically $ do
         mb_ready <- findBool =<< takeTMVar actionsVar
         case mb_ready of
-          Nothing ->
-            -- nothing left to do; return
+          Nothing -> do
+            -- Nothing left to do. Put back the TMVar so that other threads
+            -- do not block on an empty TMVar (see #249) and return.
+            putTMVar actionsVar []
             return $ return ()
           Just (this, rest) -> do
             putTMVar actionsVar rest
diff --git a/tasty.cabal b/tasty.cabal
--- a/tasty.cabal
+++ b/tasty.cabal
@@ -2,7 +2,7 @@
 --  see http://haskell.org/cabal/users-guide/
 
 name:                tasty
-version:             1.2.2
+version:             1.2.3
 synopsis:            Modern and extensible testing framework
 description:         Tasty is a modern testing framework for Haskell.
                      It lets you combine your unit tests, golden
