Updating progress on the screen problem
I am learning about asynchronous programming and i run into a problem with updating progress from async task. For some reason the task is doing its job correctly but the progress.ProgressChanged event doesn't update the progress on the screen correctly.
Result:
Press C to exit
Enter the number:
15
index: 1 progress: 1
index: 3 progress: 6
index: 3 progress: 6
index: 3 progress: 6
index: 3 progress: 6
index: 8 progress: 36
index: 9 progress: 45
index: 8 progress: 45
index: 10 progress: 55
index: 11 progress: 66
index: 15 progress: 120
index: 14 progress: 105
index: 6 progress: 21
Final result: 120
index: 13 progress: 91
index: 12 progress: 78
9 Replies
And if i add the Task.Delay(1).Wait(); in my Calc task then i will get the correct output
Result after modification:
Press C to exit
Enter the number:
15
index: 1 progress: 1
index: 2 progress: 3
index: 3 progress: 6
index: 4 progress: 10
index: 5 progress: 15
index: 6 progress: 21
index: 7 progress: 28
index: 8 progress: 36
index: 9 progress: 45
index: 10 progress: 55
index: 11 progress: 66
index: 12 progress: 78
index: 13 progress: 91
index: 14 progress: 105
index: 15 progress: 120
Final result: 120
Can this be solved without adding that line?
yes, just print the local tuple
that's happening because you're copying it to a variable
Result:
Press C to exit
Enter the number:
15
index: 2 progress: 3
index: 1 progress: 1
index: 5 progress: 15
index: 3 progress: 6
index: 4 progress: 10
index: 10 progress: 55
index: 6 progress: 21
index: 8 progress: 36
index: 7 progress: 28
index: 15 progress: 120
index: 13 progress: 91
index: 12 progress: 78
index: 9 progress: 45
index: 11 progress: 66
index: 14 progress: 105
Final result: 120
yeah i think that's just normal
it's the right data, in the wrong order
if you want synchronization, you may want an event queue sort of thing
or making the callback async and awaiting it
to be clear, the order is wrong because of WriteLine
why because WriteLine?
I think
no actually it doesn't make sense for it to do that, since the loops are synchronous
To be honest this is just an exercise so it is not something important to me 😁 but still it was odd to see result in a wrong order. I think i will stick with Task.Delay for now and i will do a little bit of research on event queue and callback async
Is this a console application?
When you do
new Progress<T>()
, it captures the current SynchronizationContext. When you do progress.Report
, it posts a message to that SynchronizationContext.
This means that if you do new Progress<T>
on the UI thread, it will capture a SynchronizationContext which will post messages back to the UI thread, which is normally what you want, as you can use the ProgressChanged
event to interact with UI elements.
However, if you do new Progress<T>()
on a thread which doesn't have a SynchronizationContext (such as the main thread of a console application), then it will capture a SynchronizationContext which just posts messages to the thread pool. This means that when you do progress.Report
, it will post the progress update to the thread pool, and any old threadpool thread will pick it up and execute it. There's no ordering guarantee in things posted to the threadpool, so you might well see progress updates arriving out of order.
That also explains why progress updates continue to happen after the final result is available: the final result Task might complete before the threadpool threads have had a chance to process all of the progress updates which were queuedAh I thought it was just a synchronous callback function
I was wondering how a blocking function could desync