1111namespace CefSharp . Internals
1212{
1313 /// <summary>
14- /// Class to store TaskCompletionSources indexed by a unique id.
14+ /// Class to store TaskCompletionSources indexed by a unique id. There are two distinct ConcurrentDictionary
15+ /// instances as we have some Tasks that are created from the browser process (EvaluateScriptAsync) calls, and
16+ /// some that are created for <see cref="IJavascriptCallback"/> instances for which the Id's are created
17+ /// in the render process.
1518 /// </summary>
1619 /// <typeparam name="TResult">The type of the result produced by the tasks held.</typeparam>
1720 public sealed class PendingTaskRepository < TResult >
1821 {
1922 private readonly ConcurrentDictionary < long , TaskCompletionSource < TResult > > pendingTasks =
2023 new ConcurrentDictionary < long , TaskCompletionSource < TResult > > ( ) ;
24+ private readonly ConcurrentDictionary < long , TaskCompletionSource < TResult > > callbackPendingTasks =
25+ new ConcurrentDictionary < long , TaskCompletionSource < TResult > > ( ) ;
2126 //should only be accessed by Interlocked.Increment
2227 private long lastId ;
2328
@@ -42,17 +47,64 @@ public KeyValuePair<long, TaskCompletionSource<TResult>> CreatePendingTask(TimeS
4247 }
4348
4449 /// <summary>
45- /// Gets and removed pending task by id.
50+ /// Creates a new pending task with a timeout.
51+ /// </summary>
52+ /// <param name="id">Id passed in from the render process</param>
53+ /// <param name="timeout">The maximum running time of the task.</param>
54+ /// <returns>The unique id of the newly created pending task and the newly created <see cref="TaskCompletionSource{TResult}"/>.</returns>
55+ public KeyValuePair < long , TaskCompletionSource < TResult > > CreateJavascriptCallbackPendingTask ( long id , TimeSpan ? timeout = null )
56+ {
57+ var taskCompletionSource = new TaskCompletionSource < TResult > ( ) ;
58+
59+ callbackPendingTasks . TryAdd ( id , taskCompletionSource ) ;
60+
61+ if ( timeout . HasValue )
62+ {
63+ taskCompletionSource = taskCompletionSource . WithTimeout ( timeout . Value , ( ) => RemoveJavascriptCallbackPendingTask ( id ) ) ;
64+ }
65+
66+ return new KeyValuePair < long , TaskCompletionSource < TResult > > ( id , taskCompletionSource ) ;
67+ }
68+
69+ /// <summary>
70+ /// If a <see cref="TaskCompletionSource{TResult}"/> is found matching <paramref name="id"/>
71+ /// then it is removed from the ConcurrentDictionary and returned.
4672 /// </summary>
4773 /// <param name="id">Unique id of the pending task.</param>
4874 /// <returns>
49- /// The <see cref="TaskCompletionSource{TResult}"/> associated with the given id.
75+ /// The <see cref="TaskCompletionSource{TResult}"/> associated with the given id
76+ /// or null if no matching TaskComplectionSource found.
5077 /// </returns>
5178 public TaskCompletionSource < TResult > RemovePendingTask ( long id )
5279 {
5380 TaskCompletionSource < TResult > result ;
54- pendingTasks . TryRemove ( id , out result ) ;
55- return result ;
81+ if ( pendingTasks . TryRemove ( id , out result ) )
82+ {
83+ return result ;
84+ }
85+
86+ return null ;
87+ }
88+
89+ /// <summary>
90+ /// If a <see cref="TaskCompletionSource{TResult}"/> is found matching <paramref name="id"/>
91+ /// then it is removed from the ConcurrentDictionary and returned.
92+ /// </summary>
93+ /// <param name="id">Unique id of the pending task.</param>
94+ /// <returns>
95+ /// The <see cref="TaskCompletionSource{TResult}"/> associated with the given id
96+ /// or null if no matching TaskComplectionSource found.
97+ /// </returns>
98+ public TaskCompletionSource < TResult > RemoveJavascriptCallbackPendingTask ( long id )
99+ {
100+ TaskCompletionSource < TResult > result ;
101+
102+ if ( callbackPendingTasks . TryRemove ( id , out result ) )
103+ {
104+ return result ;
105+ }
106+
107+ return null ;
56108 }
57109 }
58- }
110+ }
0 commit comments