diff --git a/demos/CancelQ.rb b/demos/CancelQ.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d9022f766bb7e70cfa07f2d76658f7ad9d1710b4
--- /dev/null
+++ b/demos/CancelQ.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+
+require_relative '../lib/simplekit'
+
+class MyModel
+  include SimpleKit
+
+  def init
+    @x = 1
+    schedule(:increment, rand(2), n: 1, char: 'z'.ord)
+    cancel(:increment, char: 'q'.ord)
+  end
+
+  def increment(n:, char:)
+    @x += n
+    schedule(:increment, 2.0 * rand(2), n: @x, char: char - 1, priority: 3)
+    printf "%f, %f, %c\n", model_time, @x, char
+    cancel_all :increment if model_time > 10
+  end
+end
+
+srand(42)
+MyModel.new.run
diff --git a/lib/simplekit.rb b/lib/simplekit.rb
index 0826328d8ad988147a44b8bc6d017431ea5776b7..cd63429ed20a65ea53d9102134bb623a7c0a9a58 100644
--- a/lib/simplekit.rb
+++ b/lib/simplekit.rb
@@ -1,3 +1,4 @@
+require 'set'
 require_relative 'priority_queue'
 
 # The +SimpleKit+ module provides basic event scheduling capabilities.
@@ -50,7 +51,7 @@ module SimpleKit
     #   - +event+ -> the event to be scheduled.
     #   - +delay+ -> the amount of time which should elapse before
     #     the event executes.
-    #   - +args+ -> an optional list of arguments to pass to the event
+    #   - +args+ -> zero or more named arguments to pass to the event
     #     at invocation time.
     def schedule(event, delay, **args)
       raise 'Model scheduled event with negative delay.' if delay < 0
@@ -58,7 +59,8 @@ module SimpleKit
     end
 
     def cancel(event, **args)
-      @cancel_set[event] = args
+      @cancel_set[event] ||= Set.new
+      @cancel_set[event].add(args.empty? ? nil : args)
     end
 
     def cancel_all(event)
@@ -83,8 +85,22 @@ module SimpleKit
       while (current_event = @event_list.pop)
         e = current_event.event
         if @cancel_set.key? e
-          @cancel_set.delete e # if @cancel_set[e].empty?
-          next
+          if @cancel_set[e] === nil
+            @cancel_set[e].delete nil
+            @cancel_set.delete e if @cancel_set[e].empty?
+            next
+          else
+            arg_match = false
+            for h in @cancel_set[e] do
+              if current_event.args >= h
+                arg_match = true
+                @cancel_set[e].delete h
+                @cancel_set.delete e if @cancel_set[e].empty?
+                break
+              end
+            end
+            next if arg_match
+          end
         end
         @model_time = current_event.time
         if current_event.args.empty?