简体   繁体   中英

Showing a single loadingscreen for multiple events

My app downloads from several URLs at the same time. Non of them finishes at the same time, but i only want one loading screen letting the user see that something is going on :-)

I've tried a "ticket" system, where i have a List<>. Each event that triggers a download add a ticket to the list. When they are done they remove one. I've then have a BackgroundWorker running every 200ms that checks this list. If the list count is 0 and the loadingscreen (UserControl) exists (busyscreen.GetType().Name comparison to every object in this.LayoutRoot.Children) it removes the child. If the list isnt 0 and there is no child name busyscreen it gets added.

What's wrong with this logic? I cant seem to get it to work, is there a better way to do this kind of work?

Ideally you want to use blocking and something like WaitHandle- you can make your code block until signalled to proceed

http://msdn.microsoft.com/en-us/library/system.threading.waithandle.aspx

Basically, you create an array of ManualResetEvent objects - these objects will signal to the main thread when the work is done

Then you call

WaitHandle.WaitAll(arrayOfManualResetEvents) 

which will block until the reset events are signalled

ManualResetEvent.Set()

So in pseudocode:

> Create each URL loader
> Create a ManualResetEvent for each loader
> Start each loader loading
> Call WaitHandle.WaitAll(arrayOfManualResets) which will block on your main thread
> In each URL LoadComplete handler call the associated ManualResetEvent.Set()
> The main thread will continue when all are signalled

Edit: As has been pointed out - WaitHandle.WaitAll doesn't work on Windows Phone. There's an alternative to it here:

Alternatives for WaitHandle.WaitAll on Windows Phone?

Which seems like it would do the job. Consider using it because I always find that code that ideally should block, when used with timers can work but is more fiddly and prone to bugs

You can create Singleton object that will contain LoadCount property and loadCount field (of course do not forget about INotifyProeprtyChanged ) which you can use further as you need. When you start downloading from new URL do something like Interlocked.Increment(ref loadCount); and on callback - Interlocked.Decrement(ref loadCount); .
Depending on LoadCount you can show "loading screen".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM