diff --git a/src/flexasio/FlexASIO/flexasio.cpp b/src/flexasio/FlexASIO/flexasio.cpp
index 543255a1..f6c54ac9 100644
--- a/src/flexasio/FlexASIO/flexasio.cpp
+++ b/src/flexasio/FlexASIO/flexasio.cpp
@@ -772,7 +772,7 @@ namespace flexasio {
 		return result;
 	}()),
 		hostSupportsOutputReady(preparedState.flexASIO.hostSupportsOutputReady),
-		activeStream(StartStream(preparedState.stream.get())) {}
+		activeStream(preparedState.stream.get()) {}
 
 	void FlexASIO::Stop() {
 		if (!preparedState.has_value()) throw ASIOException(ASE_InvalidMode, "stop() called before createBuffers()");
@@ -844,6 +844,14 @@ namespace flexasio {
 				memset(output_samples[output_channel_index], 0, frameCount * outputSampleSizeInBytes);
 		}
 
+		// Some backends (e.g. WASAPI) issue the first stream callback from within Pa_StartStream().
+		// This is problematic because some host applications (e.g. foo_out_asio) wait for Start() to finish
+		// before returning from bufferSwitch(), resulting in a deadlock. See: https://github.com/dechamps/FlexASIO/issues/60
+		// To work around this problem, unblock Start() if it is still running by the time we reach this point.
+		// One possible downside of this approach is that we might not report Start() errors properly if they occur
+		// after the first stream callback fires.
+		if (state == InitialState()) activeStream.EndWaitForStartOutcome();
+
 		// See dechamps_ASIOUtil/BUFFERS.md for the gory details of how ASIO buffer management works.
 
 		if (state != State::PRIMING) {
diff --git a/src/flexasio/FlexASIO/flexasio.h b/src/flexasio/FlexASIO/flexasio.h
index e29564f1..cd8473b6 100644
--- a/src/flexasio/FlexASIO/flexasio.h
+++ b/src/flexasio/FlexASIO/flexasio.h
@@ -151,7 +151,8 @@ namespace flexasio {
 				PreparedState& preparedState;
 				const bool host_supports_timeinfo;
 				const bool hostSupportsOutputReady;
-				State state = hostSupportsOutputReady ? State::PRIMING : State::PRIMED;
+				State InitialState() const { return hostSupportsOutputReady ? State::PRIMING : State::PRIMED; }
+				State state = InitialState();
 				// The index of the "unlocked" buffer (or "half-buffer", i.e. 0 or 1) that contains data not currently being processed by the ASIO host.
 				long driverBufferIndex = state == State::PRIMING ? 1 : 0;
 				std::atomic<SamplePosition> samplePosition;
@@ -162,7 +163,7 @@ namespace flexasio {
 
 				Win32HighResolutionTimer win32HighResolutionTimer;
 				Registration registration{ preparedState.runningState, *this };
-				const ActiveStream activeStream;
+				ActiveStream activeStream;
 			};
 
 			static int StreamCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) throw();
diff --git a/src/flexasio/FlexASIO/portaudio.cpp b/src/flexasio/FlexASIO/portaudio.cpp
index 70580528..f7ea3873 100644
--- a/src/flexasio/FlexASIO/portaudio.cpp
+++ b/src/flexasio/FlexASIO/portaudio.cpp
@@ -3,8 +3,25 @@
 #include "log.h"
 #include "../FlexASIOUtil/portaudio.h"
 
+#include <Objbase.h>
+#include <comdef.h>
+
 namespace flexasio {
 
+	namespace {
+
+		class COMInitializer {
+		public:
+			COMInitializer() {
+				::_com_util::CheckError(CoInitializeEx(NULL, COINIT_MULTITHREADED));
+			}
+			~COMInitializer() {
+				CoUninitialize();
+			}
+		};
+
+	}
+
 	void StreamDeleter::operator()(PaStream* stream) throw() {
 		Log() << "Closing PortAudio stream " << stream;
 		const auto error = Pa_CloseStream(stream);
@@ -28,19 +45,65 @@ namespace flexasio {
 		return Stream(stream);
 	}
 
-	void StreamStopper::operator()(PaStream* stream) throw() {
+	ActiveStream::ActiveStream(PaStream* stream) : stream(stream), startThread([this] {
+		std::exception_ptr exception;
+		try {
+			Log() << "Starting PortAudio stream " << this->stream;
+			{
+				COMInitializer comInitializer;  // Required because WASAPI Pa_StartStream() calls into the COM library
+				const auto error = Pa_StartStream(this->stream);
+				if (error != paNoError) throw std::runtime_error(std::string("unable to start PortAudio stream: ") + Pa_GetErrorText(error));
+			}
+			Log() << "PortAudio stream started";
+		}
+		catch (...) {
+		  exception = std::current_exception();
+		}
+		Log() << "Setting start outcome";
+		try {
+			if (exception)
+				promisedOutcome.set_exception(exception);
+			else
+				promisedOutcome.set_value();
+		}
+		catch (const std::future_error& future_error) {
+			if (future_error.code() != std::future_errc::promise_already_satisfied) throw;
+			Log() << "Start outcome already set";
+			return;
+		}
+		Log() << "Start outcome set";
+		}) {
+		Log() << "Waiting for start outcome";
+		promisedOutcome.get_future().get();
+		Log() << "Start outcome is OK";
+	}
+
+	ActiveStream::StartThread::~StartThread() {
+		if (thread.joinable()) {
+			Log() << "Waiting for start thread to finish";
+			thread.join();
+			Log() << "Start thread finished";
+		}
+	}
+
+	void ActiveStream::EndWaitForStartOutcome() {
+		Log() << "Ending wait for outcome";
+		try {
+			promisedOutcome.set_value();
+		}
+		catch (const std::future_error& future_error) {
+			if (future_error.code() != std::future_errc::promise_already_satisfied) throw;
+			Log() << "Start outcome already set";
+			return;
+		}
+		Log() << "Outcome wait ended";
+	}
+
+	ActiveStream::~ActiveStream() {
 		Log() << "Stopping PortAudio stream " << stream;
 		const auto error = Pa_StopStream(stream);
 		if (error != paNoError)
 			Log() << "Unable to stop PortAudio stream: " << Pa_GetErrorText(error);
 	}
 
-	ActiveStream StartStream(PaStream* const stream) {
-		Log() << "Starting PortAudio stream " << stream;
-		const auto error = Pa_StartStream(stream);
-		if (error != paNoError) throw std::runtime_error(std::string("unable to start PortAudio stream: ") + Pa_GetErrorText(error));
-		Log() << "PortAudio stream started";
-		return ActiveStream(stream);
-	}
-
 }
diff --git a/src/flexasio/FlexASIO/portaudio.h b/src/flexasio/FlexASIO/portaudio.h
index 84d4d66e..e529ce37 100644
--- a/src/flexasio/FlexASIO/portaudio.h
+++ b/src/flexasio/FlexASIO/portaudio.h
@@ -3,6 +3,8 @@
 #include <portaudio.h>
 
 #include <memory>
+#include <future>
+#include <thread>
 
 namespace flexasio {
 
@@ -12,10 +14,27 @@ namespace flexasio {
 	using Stream = std::unique_ptr<PaStream, StreamDeleter>;
 	Stream OpenStream(const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData);
 
-	struct StreamStopper {
-		void operator()(PaStream*) throw();
+	class ActiveStream {
+	public:
+		ActiveStream(PaStream*);
+		~ActiveStream();
+
+		void EndWaitForStartOutcome();
+
+	private:
+		class StartThread {
+		public:
+			template <typename... Args> StartThread(Args&&... args) : thread(std::forward<Args>(args)...) {}
+			~StartThread();
+
+		private:
+			std::thread thread;
+		};
+
+		PaStream* const stream;
+
+		std::promise<void> promisedOutcome;
+		StartThread startThread;
 	};
-	using ActiveStream = std::unique_ptr<PaStream, StreamStopper>;
-	ActiveStream StartStream(PaStream*);
 
 }