/// <summary> /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use. /// Builds all the stuff up, constructs the DownloaderManager. Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it. /// **NOTE: this follows a variant of the Builder Pattern, where we delegate constuction of a complex object. /// could also have been in a separate Builder or Factory class but small enough to put here. /// </summary> /// <param name="application">the name of the Updater target application</param> /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns> private DnldMgrHolder SetupDownloadManager(ApplicationConfiguration application) { DownloaderManager dnldMgr = null; // create an instance of a Downloader for DownloaderManager to use: IDownloader downloader = DownloaderFactory.Create(UpdaterConfiguration.Instance); // create instance of Validator for DownloaderManager to use: IValidator validator = ValidatorFactory.Create(UpdaterConfiguration.Instance); // populate application jobentry for shared DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry(application.Name, Guid.Empty, JobStatus.Ready); // create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr ManualResetEvent mustStop = new ManualResetEvent(false); // create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly: BadExitCallback badExitCbk = new BadExitCallback(this.RestartUpdater); // create the download manager, feed it our instance of actual downloader dnldMgr = new DownloaderManager(downloader, validator, dnldJob, mustStop, badExitCbk); // create the thread that this dnldMgr + its other objects will run on Thread dnldThread = new Thread(new ThreadStart(dnldMgr.RunDownloader)); dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString(); // create new holder struct for thread + dnldmgr DnldMgrHolder holder = new DnldMgrHolder(dnldThread, dnldMgr); #region Event Registrations // *** NOTE: we facade all these underlying events through this class to // *** a) avoid exposing dnldMgr class // *** b) so later if we choose to use a better threading model--that is, NOT allow // *** our threads to "venture outside" and possibly dawdle out there (get blocked for instance) // *** then it will be easy to spawn a dedicated eventing thread in here. // *** NOTE: IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events. // *** the sinking app will have to distinguish which app fired which event from the event args // REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so // we shuttle its events through this class dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler(OnServerManifestDownloaded); dnldMgr.UpdateAvailable += new UpdaterActionEventHandler(OnUpdateAvailable); dnldMgr.DownloadStarted += new UpdaterActionEventHandler(OnDownloadStarted); dnldMgr.DownloadCompleted += new UpdaterActionEventHandler(OnDownloadCompleted); dnldMgr.ManifestValidated += new UpdaterActionEventHandler(OnManifestValidated); dnldMgr.ManifestValidationFailed += new UpdaterActionEventHandler(OnManifestValidationFailed); dnldMgr.FilesValidated += new UpdaterActionEventHandler(OnFilesValidated); dnldMgr.FilesValidationFailed += new UpdaterActionEventHandler(OnFilesValidationFailed); #endregion // return the packaged DnldMgr return(holder); }
/// <summary> /// Updater start method /// </summary> /// <remarks> /// This method iterates through the applications to update, and starts each on its own thread /// </remarks> public void StartUpdater() { // lock the holder collection while we iterate through it lock (_dnldHolders.SyncRoot) { // cycle through collection of holders, starting each thread foreach (DictionaryEntry de in _dnldHolders) { DnldMgrHolder holder = (DnldMgrHolder)de.Value; // start the thread holder.dnldThread.Start(); // announce we have started: ApplicationUpdateManager.TraceWrite( "[ApplicationUpdateManager.StartUpdater]", "RESX_MESSAGE_UpdaterStarted", holder.dnldMgr.ApplicationName, DateTime.Now.ToString(Resource.ResourceManager["RESX_DateTimeToStringFormat"], CultureInfo.CurrentCulture)); } } }
/// <summary> /// Does all the setup of a DownloaderManager, including using Factories to construct Validators and Downloaders that it will use. /// Builds all the stuff up, constructs the DownloaderManager. Packages the Mgr with its Thread in a DnldMgrHolder struct and returns it. /// **NOTE: this follows a variant of the Builder Pattern, where we delegate constuction of a complex object. /// could also have been in a separate Builder or Factory class but small enough to put here. /// </summary> /// <param name="application">the name of the Updater target application</param> /// <returns>DnldMgrHolder struct containing Built DownloaderManager and the Thread it will run on</returns> private DnldMgrHolder SetupDownloadManager( ApplicationConfiguration application ) { DownloaderManager dnldMgr = null; // create an instance of a Downloader for DownloaderManager to use: IDownloader downloader = DownloaderFactory.Create( UpdaterConfiguration.Instance ); // create instance of Validator for DownloaderManager to use: IValidator validator = ValidatorFactory.Create( UpdaterConfiguration.Instance ); // populate application jobentry for shared DownloadJobStatusEntry dnldJob = new DownloadJobStatusEntry( application.Name, Guid.Empty, JobStatus.Ready ); // create the ManualResetEvent "mustStop" which we will use later if Stopping to signal "you must stop" to dnld mgr ManualResetEvent mustStop = new ManualResetEvent( false ); // create the callback delegate pointed at our RestartUpdater method so we can restart if something fails badly: BadExitCallback badExitCbk = new BadExitCallback( this.RestartUpdater ); // create the download manager, feed it our instance of actual downloader dnldMgr = new DownloaderManager( downloader, validator, dnldJob, mustStop, badExitCbk ); // create the thread that this dnldMgr + its other objects will run on Thread dnldThread = new Thread( new ThreadStart( dnldMgr.RunDownloader ) ); dnldThread.Name = "DownloadManagerThread_" + application.Name + "_" + _guidUniqueName.ToString(); // create new holder struct for thread + dnldmgr DnldMgrHolder holder = new DnldMgrHolder( dnldThread, dnldMgr ); #region Event Registrations // *** NOTE: we facade all these underlying events through this class to // *** a) avoid exposing dnldMgr class // *** b) so later if we choose to use a better threading model--that is, NOT allow // *** our threads to "venture outside" and possibly dawdle out there (get blocked for instance) // *** then it will be easy to spawn a dedicated eventing thread in here. // *** NOTE: IF we have more than one app we're updating, then we must hook EACH DOWNLOADMANAGER's events. // *** the sinking app will have to distinguish which app fired which event from the event args // REGISTER for DownloaderManager's events--we do not want to expose downloader directly, so // we shuttle its events through this class dnldMgr.ServerManifestDownloaded += new UpdaterActionEventHandler( OnServerManifestDownloaded ); dnldMgr.UpdateAvailable += new UpdaterActionEventHandler( OnUpdateAvailable ); dnldMgr.DownloadStarted += new UpdaterActionEventHandler( OnDownloadStarted ); dnldMgr.DownloadCompleted += new UpdaterActionEventHandler( OnDownloadCompleted ); dnldMgr.ManifestValidated +=new UpdaterActionEventHandler( OnManifestValidated ); dnldMgr.ManifestValidationFailed +=new UpdaterActionEventHandler( OnManifestValidationFailed ); dnldMgr.FilesValidated +=new UpdaterActionEventHandler( OnFilesValidated ); dnldMgr.FilesValidationFailed +=new UpdaterActionEventHandler( OnFilesValidationFailed ); #endregion // return the packaged DnldMgr return holder; }