@@ -67,6 +67,11 @@ internal unsafe struct DispatcherQueueProxyHandler2 : IDispatcherQueueHandler
67
67
/// </summary>
68
68
private GCHandle state2Handle ;
69
69
70
+ /// <summary>
71
+ /// The generic stub to invoke the current callback with the right generic context.
72
+ /// </summary>
73
+ private delegate * < DispatcherQueueProxyHandler2 * , int > stub ;
74
+
70
75
/// <summary>
71
76
/// The current reference count for the object (from <c>IUnknown</c>).
72
77
/// </summary>
@@ -75,18 +80,23 @@ internal unsafe struct DispatcherQueueProxyHandler2 : IDispatcherQueueHandler
75
80
/// <summary>
76
81
/// Creates a new <see cref="DispatcherQueueProxyHandler2"/> instance for the input callback and state.
77
82
/// </summary>
83
+ /// <typeparam name="T1">The type of the first state to capture.</typeparam>
84
+ /// <typeparam name="T2">The type of the second state to capture.</typeparam>
78
85
/// <param name="handler">The input <see cref="DispatcherQueueHandler{T1,T2}"/> callback to enqueue.</param>
79
86
/// <param name="state1">The first input state to capture and pass to the callback.</param>
80
87
/// <param name="state2">The second input state to capture and pass to the callback.</param>
81
88
/// <returns>A pointer to the newly initialized <see cref="DispatcherQueueProxyHandler2"/> instance.</returns>
82
- public static DispatcherQueueProxyHandler2 * Create ( object handler , object state1 , object state2 )
89
+ public static DispatcherQueueProxyHandler2 * Create < T1 , T2 > ( DispatcherQueueHandler < T1 , T2 > handler , T1 state1 , T2 state2 )
90
+ where T1 : class
91
+ where T2 : class
83
92
{
84
93
DispatcherQueueProxyHandler2 * @this = ( DispatcherQueueProxyHandler2 * ) Marshal . AllocHGlobal ( sizeof ( DispatcherQueueProxyHandler2 ) ) ;
85
94
86
95
@this ->lpVtbl = Vtbl ;
87
96
@this ->callbackHandle = GCHandle . Alloc ( handler ) ;
88
97
@this ->state1Handle = GCHandle . Alloc ( state1 ) ;
89
98
@this ->state2Handle = GCHandle . Alloc ( state2 ) ;
99
+ @this ->stub = & Impl . Invoke < T1 , T2 > ;
90
100
@this ->referenceCount = 1 ;
91
101
92
102
return @this ;
@@ -183,15 +193,26 @@ public static uint Release(DispatcherQueueProxyHandler2* @this)
183
193
/// </summary>
184
194
[ UnmanagedCallersOnly ]
185
195
public static int Invoke ( DispatcherQueueProxyHandler2 * @this )
196
+ {
197
+ return @this ->stub ( @this ) ;
198
+ }
199
+
200
+ /// <summary>
201
+ /// Implements <c>IDispatcherQueueHandler.Invoke()</c> from within a generic context.
202
+ /// </summary>
203
+ public static int Invoke < T1 , T2 > ( DispatcherQueueProxyHandler2 * @this )
204
+ where T1 : class
205
+ where T2 : class
186
206
{
187
207
object callback = @this ->callbackHandle . Target ! ;
188
208
object state1 = @this ->state1Handle . Target ! ;
189
209
object state2 = @this ->state2Handle . Target ! ;
190
210
191
211
try
192
212
{
193
- // Same optimization as in DispatcherQueueProxyHandler1
194
- Unsafe . As < DispatcherQueueHandler < object , object > > ( callback ) ( state1 , state2 ) ;
213
+ Unsafe . As < DispatcherQueueHandler < object , object > > ( callback ) (
214
+ Unsafe . As < T1 > ( state1 ) ,
215
+ Unsafe . As < T2 > ( state2 ) ) ;
195
216
}
196
217
catch ( Exception e )
197
218
{
0 commit comments