/// <summary> /// Attempt to implement the worker item on this thread /// </summary> /// <param name="workItem"></param> public void ExecuteWorkItem(WorkerItem workItem) { if (!_isAvailable) { throw new InvalidOperationException("Thread is busy"); } _task = workItem._delegate; _isAvailable = false; _waitForNewTask.Set(); }
/// <summary> /// Update the library when invoked via the timer /// </summary> private void UpdateLibrary() { try { // get a hook to the DB IDBClient db = Database.RetrieveClient(); // retrieve the initial number of tracks int beforeTracks = Database.RetrieveNumberOfTracks(db); // get the audio library locations IList<AudioLibraryLocation> locations = Database.RetrieveLibraryLocations(db); // get the current timestamp, we'll use this in case anything gets modified while this is happening DateTime beforeUpdate = DateTime.Now; _log.Info("Starting library update at: " + beforeUpdate.ToLocalTime()); try { // recurse through each of the library locations foreach (AudioLibraryLocation location in locations) { if (_log.IsDebugEnabled) { _log.Debug("Updating library location: " + location.Path); } // initialise the list of directories to process IList<string> directoriesToProcess = new List<string>(); // start traversing down each directory ProcessDirectory(directoriesToProcess, location.Path, location.LastWritten); // if there was any processing needed to be done if (directoriesToProcess.Count > 0) { const int numThreads = 5; _libraryThreadPool = new FixedThreadPool(5, ThreadPriority.Lowest); _log.Debug("Created custom thread pool for library with " + numThreads + " threads"); // make all the workers for (int i = 0; i < directoriesToProcess.Count; i++) { var worker = new AudioLibraryWorker(); worker.Directory = directoriesToProcess[i]; // attach it to a worker for the pool var workerItem = new WorkerItem(worker.WorkerMethod); // add it to the pool _libraryThreadPool.QueueWorkerItem(workerItem); // start the show _libraryThreadPool.Start(); } } // reset the reference to when this update run started location.LastWritten = beforeUpdate; // store this updated location back in the DB Database.UpdateAddLibraryLocation(db, location); // commit after each location. if something goes wrong, we wont have to redo db.Commit(); } // get the number of tracks after int afterTracks = Database.RetrieveNumberOfTracks(db); TimeSpan elapsedTime = DateTime.Now - beforeUpdate; _log.Info("Finished library update at: " + DateTime.Now.ToLocalTime() + ". Took: " + elapsedTime.TotalSeconds + " seconds"); _log.Info("Imported " + (afterTracks - beforeTracks) + " tracks"); // close the db db.Close(); } catch (DatabaseClosedException) { _log.Debug("The database has been closed prematurely"); } } catch (Db4oException ex) { _log.Error("Problem occurred when updating library", ex); } finally { _libraryUpdateTimer.Start(); } }
/// <summary> /// Add the supplied item to the queue /// </summary> /// <param name="workerItem"></param> public void QueueWorkerItem(WorkerItem workerItem) { _theQueue.Enqueue(workerItem); _queueModified.Set(); }