Answered by:
Task.WhenAll Not Working

Question
-
I have several tasks which involve binding collections to ItemsCollections for which I want to do concurrently using Task.WhenAll (or whatever the appropriate method is, if I am wrong). My current code is:
Private Async Function BindAll() As Task System.Diagnostics.Debug.WriteLine("BindAll - Start") Dim bindingtasks As New List(Of Task) If Me.chkDisplayRound.IsChecked Then bindingtasks.Add(New Task(AddressOf Me.BindRoundNumbers)) If Me.players IsNot Nothing AndAlso Me.players.Any Then bindingtasks.Add(New Task(AddressOf Me.BindNames)) bindingtasks.Add(New Task(AddressOf Me.BindScores)) If Me.radCumulative.IsChecked Then bindingtasks.Add(New Task(AddressOf Me.BindTotals)) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 1") Await Task.WhenAll(bindingtasks) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 2") 'Scroll to make the current score visible Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() Me.scrScores.ScrollToRequired(Me.GetRequiredVisible())) Me.stkEnterNames.Visibility = Visibility.Collapsed Else : Me.stkEnterNames.Visibility = Visibility.Visible End If System.Diagnostics.Debug.WriteLine("BindAll - End") End Function
My code locks up at Await Task.WhenAll(bindingtasks) (between Checkpoint 1 and Checkpoint 2). If I call the methods that I am making into Tasks (BindRoundNumbers(), BindNames(), BindScores(), and BindTotals()) individually, everything is fine, but I want to call them concurrently. What am I doing wrong? Thanks.
Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/
Wednesday, August 20, 2014 2:39 AM
Answers
-
You should use the Task.Run or TaskFactory.StartNew methods when you create a new task and not the Task constructor. Using any of these metods to create a task will start the task immediately after it has been created:
Private Async Function BindAll() As Task System.Diagnostics.Debug.WriteLine("BindAll - Start") Dim bindingtasks As New List(Of Task) If Me.chkDisplayRound.IsChecked Then bindingtasks.Add(Task.Run(AddressOf Me.BindRoundNumbers)) If Me.players IsNot Nothing AndAlso Me.players.Any Then bindingtasks.Add(Task.Run(AddressOf Me.BindNames)) bindingtasks.Add(Task.Run(AddressOf Me.BindScores)) If Me.radCumulative.IsChecked Then bindingtasks.Add(Task.Run(AddressOf Me.BindTotals)) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 1") Await Task.WhenAll(bindingtasks) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 2") 'Scroll to make the current score visible Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() Me.scrScores.ScrollToRequired(Me.GetRequiredVisible())) Me.stkEnterNames.Visibility = Visibility.Collapsed Else : Me.stkEnterNames.Visibility = Visibility.Visible End If System.Diagnostics.Debug.WriteLine("BindAll - End") End Function
- Marked as answer by Herro wongMicrosoft contingent staff, Moderator Tuesday, September 9, 2014 8:01 AM
Thursday, August 21, 2014 12:32 PM
All replies
-
Hi Nathan,
While you bind those tasks into bindingtask collection, have you call the Task.Start() method?
For Each task As var In tasks task.Start() Next
Or you can use Task.Factory.StartNew to initialize a task and run it immediately. See this for more information: StartNew Method (Action), then you could use the following code to deal with the result.
await Task.Factory.ContinueWhenAll(tasks.ToArray(), continueworks => { //do somthing to the reuslt foreach (var work in continueworks) { int result = work.Result; } });
--James
<THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
Thanks
MSDN Community Support
Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.Thursday, August 21, 2014 11:20 AMModerator -
You should use the Task.Run or TaskFactory.StartNew methods when you create a new task and not the Task constructor. Using any of these metods to create a task will start the task immediately after it has been created:
Private Async Function BindAll() As Task System.Diagnostics.Debug.WriteLine("BindAll - Start") Dim bindingtasks As New List(Of Task) If Me.chkDisplayRound.IsChecked Then bindingtasks.Add(Task.Run(AddressOf Me.BindRoundNumbers)) If Me.players IsNot Nothing AndAlso Me.players.Any Then bindingtasks.Add(Task.Run(AddressOf Me.BindNames)) bindingtasks.Add(Task.Run(AddressOf Me.BindScores)) If Me.radCumulative.IsChecked Then bindingtasks.Add(Task.Run(AddressOf Me.BindTotals)) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 1") Await Task.WhenAll(bindingtasks) System.Diagnostics.Debug.WriteLine("BindAll - Checkpoint 2") 'Scroll to make the current score visible Await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, Sub() Me.scrScores.ScrollToRequired(Me.GetRequiredVisible())) Me.stkEnterNames.Visibility = Visibility.Collapsed Else : Me.stkEnterNames.Visibility = Visibility.Visible End If System.Diagnostics.Debug.WriteLine("BindAll - End") End Function
- Marked as answer by Herro wongMicrosoft contingent staff, Moderator Tuesday, September 9, 2014 8:01 AM
Thursday, August 21, 2014 12:32 PM