c# - Not every result of IProgress<int> comes out of the task -


consider following implementation, method accepts iprogress<int>, iterates on 10000 objects. numbers array variable returns 10000 objects, iprogress<int> reports between 9970 - 9980 objects. varies per run, "lost".

    protected async override task<int[]> collectdataasyncimpl(iprogress<int> progress) {                         return await task.run<int[]>(() => {              var numbers = new list<int>();              foreach (var idx in new int32range(1, 10000).asenumerable().index()) {                                                              numbers.add(idx.value);                                      if (progress != null) {                     progress.report(idx.value);                 }              }              return numbers.toarray();         });     } 

as reference, here's test ran. fails @ third assert assert.equal(10000, result[9999]);.

[fact] async void reportsprogress() {                 var sut = new integercollector();     var result = new list<int>();     var output = await sut.collectdataasync(new progress<int>(i => result.add(i)));     assert.equal(10000, output.length);     assert.equal(1, result[0]);     assert.equal(10000, result[9999]); } 

clearly i'm doing wrong, or don't understand internals of task/threading. implementation of iprogress<int> new progress<int>(i => result.add(i)) not correct? should make thread safe, , if so, how do that?

github has code can clone & test if need be: https://github.com/kodefoxx/kf.datacollection/tree/master/source/kf.datacollection

it because of how progress<t> implemented. when created, progress<t> captures synchronization context , uses execute i => result.add(i). since running test, assume there no synchronization context. in case progress<t> uses default synchronizationcontext, posts work items thread pool (threadpool.queueuserworkitem). task completes before thread pool processes queued items, , explains results inconsistency.

a simple way check if case: change iprogress<int> argument action<int> , pass i => result.add(i) delegate directly, without wrapping progress<t>.


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -