@@ -158,34 +158,51 @@ public virtual void SetParameters(ParameterCollection parameters)
158
158
_hasCalledInit = true ;
159
159
OnInit ( ) ;
160
160
161
- // If you override OnInitAsync and return a nonnull task, then by default
161
+ // If you override OnInitAsync and return a noncompleted task, then by default
162
162
// we automatically re-render once that task completes.
163
163
var initTask = OnInitAsync ( ) ;
164
- if ( initTask != null && initTask . Status != TaskStatus . RanToCompletion )
165
- {
166
- initTask . ContinueWith ( ContinueAfterLifecycleTask ) ;
167
- }
164
+ ContinueAfterLifecycleTask ( initTask ) ;
168
165
}
169
166
170
167
OnParametersSet ( ) ;
171
168
var parametersTask = OnParametersSetAsync ( ) ;
172
- if ( parametersTask != null && parametersTask . Status != TaskStatus . RanToCompletion )
173
- {
174
- parametersTask . ContinueWith ( ContinueAfterLifecycleTask ) ;
175
- }
169
+ ContinueAfterLifecycleTask ( parametersTask ) ;
176
170
177
171
StateHasChanged ( ) ;
178
172
}
179
173
180
- private void ContinueAfterLifecycleTask ( Task task )
174
+ private async void ContinueAfterLifecycleTask ( Task task )
181
175
{
182
- if ( task . Exception == null )
183
- {
184
- StateHasChanged ( ) ;
185
- }
186
- else
176
+ switch ( task == null ? TaskStatus . RanToCompletion : task . Status )
187
177
{
188
- HandleException ( task . Exception ) ;
178
+ // If it's already completed synchronously, no need to await and no
179
+ // need to issue a further render (we already rerender synchronously).
180
+ // Just need to make sure we propagate any errors.
181
+ case TaskStatus . RanToCompletion :
182
+ case TaskStatus . Canceled :
183
+ break ;
184
+ case TaskStatus . Faulted :
185
+ HandleException ( task . Exception ) ;
186
+ break ;
187
+
188
+ // For incomplete tasks, automatically re-render on successful completion
189
+ default :
190
+ try
191
+ {
192
+ await task ;
193
+ StateHasChanged ( ) ;
194
+ }
195
+ catch ( Exception ex )
196
+ {
197
+ // Either the task failed, or it was cancelled, or StateHasChanged threw.
198
+ // We want to report task failure or StateHasChanged exceptions only.
199
+ if ( ! task . IsCanceled )
200
+ {
201
+ HandleException ( ex ) ;
202
+ }
203
+ }
204
+
205
+ break ;
189
206
}
190
207
}
191
208
@@ -203,18 +220,12 @@ private static void HandleException(Exception ex)
203
220
void IHandleEvent . HandleEvent ( EventHandlerInvoker binding , UIEventArgs args )
204
221
{
205
222
var task = binding . Invoke ( args ) ;
223
+ ContinueAfterLifecycleTask ( task ) ;
206
224
207
225
// After each event, we synchronously re-render (unless !ShouldRender())
208
226
// This just saves the developer the trouble of putting "StateHasChanged();"
209
227
// at the end of every event callback.
210
228
StateHasChanged ( ) ;
211
-
212
- if ( task . Status == TaskStatus . RanToCompletion )
213
- {
214
- return ;
215
- }
216
-
217
- task . ContinueWith ( ContinueAfterLifecycleTask ) ;
218
229
}
219
230
220
231
void IHandleAfterRender . OnAfterRender ( )
0 commit comments