views:

95

answers:

1

I'm writing a simple photo downloader application using IOC. There is a fairly straightforward list of steps. Get list of photos to download. Check this, Check that, then download. The download can be accomplished via FTP in some cases, and via http in others, and via a web service in others.

What I'm wondering, as I'm new to IOC land, is what is a good pattern to use to spin up 10 'download threads' using IOC best practices/design patterns.

I'm using Castle Windsor but could easily switch to StructureMap, or Spring, as I'm early in the process.

EDIT: To be clear, I understand how to create an IPhotoDownloader interface and then 3 concrete photodownloader classes, what I'm not clear on is how to control the threading and how to know when everything is done on all the threads and continue.

Second Edit in response to comments: As I understand it, it would be bad to directly reference a concrete class in an IOC application so if I wanted to, for instance, use ThreadPool.QueueUserWorkItem to multithread my downloader, how would I do that. Would I simply use the container to resolve the concrete class I want on each thread inside my thread start method? like:

void StartThead(){
PhotoRetriever retriever = container.Resolve<PhotoRetriever>();
}
A: 

Krysztof got me started on the right path, basically I was seeing some weird behavior when doing something like this:

    _fileList = new Stack<Uri>();
            for (int i = 0; i < 10; i++)
            {
                _fileList.Push(new Uri("http://mi.mirror.garr.it/mirrors/postfix/index.html"));
                _fileList.Push(new Uri("ftp://mi.mirror.garr.it/mirrors/postfix/index.html"));
                _fileList.Push(new Uri("http://www.google.com/adsense/static/it/LocalizedTerms.html"));
                _fileList.Push(new Uri("http://www.cnn.com"));
            }

            _handles = new ManualResetEvent[ThreadCount];
            _watch.Start();

            // fire up threadCount threads to download files
            for (int i = 0; i < ThreadCount; i++)
            {
                _handles[i] = new ManualResetEvent(false);
                ThreadPool.QueueUserWorkItem(new WaitCallback(downloadThread), i);
            }

            // wait for all threads to finish
            WaitHandle.WaitAll(_handles);

................

 private void downloadThread(object stateInformation)
        {
            var retriever = _IOCContainer.Resolve<HtmlTitleRetriever>();

while (fileUri != null) {

            var fName = retriever.DownLoadFile(fileUri);


.....

The behavior I was seeing was because I was not aware of the lifetime properties, default Singleton, when in fact I needed to use PerThread in this instance.

Tom DeMille

related questions