Skip to content

Commit de30802

Browse files
committed
Minor perf improvement to clr.async.task/result and clr.async.task/task-result.
1 parent 2df8488 commit de30802

File tree

1 file changed

+13
-11
lines changed
  • Clojure/Clojure.Source/clojure/clr/async

1 file changed

+13
-11
lines changed

Clojure/Clojure.Source/clojure/clr/async/task.clj

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,29 @@
44
(:refer-clojure :exclude [await])
55
(:import [System.Threading.Tasks Task]))
66

7-
(set! *warn-on-reflection* true)
87

98
;; ── Internal helpers ──────────────────────────────────────────────────
109

10+
; This would get a reflection warning, so we don't turn on *warn-on-reflection* until after.
11+
; We WANT a reflection warning -- we need the DLR callsite mechanism on the call to .GetAwaiter.
12+
; If we tag the task parameter as ^Task, we always pick up Task.GetAwaiter(), even for generic Task<TResult> tasks.
13+
; That just does not work.
14+
1115
(defn- task-result
1216
"Extracts the result from a completed Task<T> via its typed awaiter.
1317
Uses GetAwaiter().GetResult() which unwraps exceptions cleanly
1418
(no AggregateException wrapping unlike .Result).
1519
Returns nil for non-generic Task (void)."
16-
[^Task task]
17-
(let [t (.GetType task)]
20+
[task]
21+
(let [t (.GetType ^Object task)]
1822
(when (.IsGenericType t)
1923
(let [^Type type-arg (aget (.GetGenericArguments t) 0)]
2024
(when-not (= "VoidTaskResult" (.Name type-arg))
21-
(let [awaiter (.Invoke (.GetMethod t "GetAwaiter" Type/EmptyTypes) task nil)]
22-
(.Invoke (.GetMethod (.GetType ^Object awaiter) "GetResult" Type/EmptyTypes)
23-
awaiter nil)))))))
25+
(-> task .GetAwaiter .GetResult))))))
26+
27+
28+
(set! *warn-on-reflection* true)
29+
2430

2531
;; ── Macros (only these two require macro status) ──────────────────────
2632

@@ -127,9 +133,5 @@
127133
(t/result (t/->task 42)) ;=> 42
128134
(t/result (t/completed-task)) ;=> nil
129135
(t/result (t/async (t/await (t/delay-task 100)) \"done\")) ;=> \"done\""
130-
[^Task task]
131-
;; Block until complete. Non-generic GetResult() handles void tasks
132-
;; and throws inner exception (not AggregateException) on fault.
133-
(-> task .GetAwaiter .GetResult)
134-
;; For Task<T>, extract the typed result via the generic awaiter.
136+
[task]
135137
(task-result task))

0 commit comments

Comments
 (0)