             super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
             return
         }
-        
-        guard shouldEvaluateConditions() else { return }
-        
-        observerValueChangedQueue.async {
-            guard self.shouldEvaluateConditions() else { return }
-            self.evaluateConditions()
-        }
-    }
-    
-    private func shouldEvaluateConditions() -> Bool {
-        return super.isReady && !self.isCancelled && self.state == .pending
-    }
-
+        stateAccess.lock()
+        defer { stateAccess.unlock() }
+        guard super.isReady && !isCancelled && state == .pending else { return }
+        evaluateConditions()
+    }
+    
     /**
         Indicates that the Operation can now begin to evaluate readiness conditions,
         if appropriate.
     */
     func didEnqueue() {
+        stateAccess.lock()
+        defer { stateAccess.unlock() }
         state = .pending
     }
     
+    private let stateAccess = NSRecursiveLock()
     /// Private storage for the `state` property that will be KVO observed.
     private var _state = State.initialized
     private let stateQueue = DispatchQueue(label: "Operations.Operation.state")

        state = .evaluatingConditions
        
        OperationConditionEvaluator.evaluate(conditions, operation: self) { failures in
            if !failures.isEmpty {
                self.cancelWithErrors(failures)
            }

            return currentState
        }
        set {
//            guard newValue != _state else { return }
            /*
             It's important to note that the KVO notifications are NOT called from inside
             the lock. If they were, the app would deadlock, because in the middle of
