As I promised a while ago, here is my answer to follow-up question.
If the method
DownloadFile
should be repeated many times, approach should be very different.
You should create a separate thread and start if from the very beginning (more exactly, when the application main form is shown, use the event
Shown
). Use regular
System.Threading.Thread
. The thread should be kept sleeping and wake up only when their input data is fed to them. It means you need to use some synchronization primitives (I would suggest
System.Threading.EventWaitHandle
,
System.Threading.AutoResetEvent
or
System.Threading.ManualResetEvent
). The thread is waiting at the call to
EventWaitHandle.WaitOne
and awakened by calling
EventWaitHandle.Set
from another thread (for example, UI thread) when new task is ready, complete full cycle (possibly with exception due to some failure) and comes back, repeating download cycle in infinite loop. Be sure to use locking for exchange of task data between thread.
For this particular task more specialized tool should be used: a blocking message queue. Your application makes a queue of download task (some type encapsulating URL, output file name and other parameters) which is fed to the downloading thread; the queue should be blocking, to avoid spin-wait.
You can find complete well tested generic implementation and usage sample in my Tips/Trick article:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[
^]. In the queue-based implementation, locking should not be used: the queue already provides propert synchronization.
The thread should notify the UI not directly (to show download status, etc.), but using
Control.Invoke
. This mechanism makes sure that UI properties/methods are not called by the non-UI thread but put to the queue, so actually calls are done in UI thread. By the way, my article referenced above provides pretty good explanation of how this invocation mechanism works.
Good luck,
—SA