/// <summary> /// Returns the Thread of a queued/running task. /// </summary> /// <param name="task">Task</param> /// <returns>Thread. If the task is not queued/running, it returns null</returns> public static Thread GetTaskThread(Enum task) { if (!queuedTasks.ContainsKey(task)) { return(null); } int its = 0, maxIts = 10; ThreadWorkerTaskBase tw = (ThreadWorkerTaskBase)queuedTasks[task]; Thread t = tw.WorkerThread; while (t == null) { // ThreadPool task: queued but not yet started, wait... Thread.Sleep(100); if (!queuedTasks.ContainsKey(task)) { return(null); } tw = (ThreadWorkerTaskBase)queuedTasks[task]; t = tw.WorkerThread; if (++its > maxIts) { break; // do not iterate forever } } return(t); }
/// <summary> /// Execute a task in synchronized manner. /// </summary> /// <param name="task">Task to start</param> /// <param name="action">DuplicateTaskQueued</param> /// <returns>An Exception object on any failure within the task, /// or null if the task was successfully finished or cancelled.</returns> public static Exception RunTaskSynchronized(ThreadWorkerTaskBase task, DuplicateTaskQueued action) { if (IsTaskQueued(task.TaskID)) { if (action == DuplicateTaskQueued.Ignore) { return(null); } if (action != DuplicateTaskQueued.Allowed) // wait, or abort running task thread { if (action == DuplicateTaskQueued.Abort) { AbortTask(task.TaskID); } if (action != DuplicateTaskQueued.Wait) { WaitForTask(task.TaskID); } } } ThreadWorkerBase wc = task.GetWorkerInstance(); queuedTasks.Add(task.TaskID, task); try { return(wc.LocalRunProcess()); } finally { queuedTasks.Remove(task); } }
private bool RaiseBackroundTaskStarted(ThreadWorkerTaskBase task) { if (OnBackgroundTaskStarted != null) { ThreadWorkerProgressArgs args = new ThreadWorkerProgressArgs(task.TaskID, 1, 0, null, false, null); OnBackgroundTaskStarted(task.WorkerThread, args); } return(false); }
/// <summary> /// Queue a task using a freshly created Thread. /// </summary> /// <param name="task">Task to start</param> /// <param name="action">DuplicateTaskQueued</param> /// <returns>True, if the task was successfully started, else false.</returns> public static bool StartTask(ThreadWorkerTaskBase task, DuplicateTaskQueued action) { if (waitForGlobalThreadResource) { // delay startup of the thread if (IsTaskWaitingForGlobalThreadResource(task.TaskID)) { if (action == DuplicateTaskQueued.Ignore) { return(false); } if (action != DuplicateTaskQueued.Allowed) { return(false); // we do not have to wait/abort, they are not yet even started anyway } } TaskStartInfo startInfo = new TaskStartInfo(TaskStartInfo.StartMethod.ThreadStart, task, action); taskStartInfos.Enqueue(startInfo); return(true); } if (IsTaskQueued(task.TaskID)) { if (action == DuplicateTaskQueued.Ignore) { return(false); } if (action != DuplicateTaskQueued.Allowed) // wait, or abort running task thread { if (action == DuplicateTaskQueued.Abort) { AbortTask(task.TaskID); } if (action != DuplicateTaskQueued.Wait) { WaitForTask(task.TaskID); } } } ThreadWorkerBase wc = task.GetWorkerInstance(); Thread t = new Thread(new ThreadStart(wc.RunProcess)); t.IsBackground = true; //make them a daemon - prevent thread callback issues task.WorkerThread = t; t.Start(); queuedTasks.Add(task.TaskID, task); return(true); }
/// <summary> /// Queue a task using ThreadPool. /// </summary> /// <param name="task">Task to start</param> /// <param name="action">Duplicate task action</param> /// <returns>True, if the task was successfully queued up /// to the ThreadPool, else false.</returns> public static bool QueueTask(ThreadWorkerTaskBase task, DuplicateTaskQueued action) { if (waitForGlobalThreadResource) { // delay startup of the thread if (IsTaskWaitingForGlobalThreadResource(task.TaskID)) { if (action == DuplicateTaskQueued.Ignore) { return(false); // yet waiting } if (action != DuplicateTaskQueued.Allowed) { return(false); // we do not have to wait/abort, they are not yet even started anyway } } TaskStartInfo startInfo = new TaskStartInfo(TaskStartInfo.StartMethod.ThreadPool, task, action); taskStartInfos.Enqueue(startInfo); return(true); } if (IsTaskQueued(task.TaskID)) { if (action == DuplicateTaskQueued.Ignore) { return(false); } if (action != DuplicateTaskQueued.Allowed) // wait, or abort running task thread { if (action == DuplicateTaskQueued.Abort) { AbortTask(task.TaskID); } if (action != DuplicateTaskQueued.Wait) { WaitForTask(task.TaskID); } } } queuedTasks.Add(task.TaskID, task); ThreadWorkerBase wc = task.GetWorkerInstance(); return(ThreadPool.QueueUserWorkItem(new WaitCallback(wc.RunProcess))); }
/// <summary> /// Method for ThreadPool QueueWorkerItem /// </summary> /// <param name="obj"></param> public void RunProcess(object obj) { Thread.CurrentThread.IsBackground = true; //make them a daemon if (queuedTasks.ContainsKey(task.TaskID)) // add Thread ref. to enable cancel/suspend, etc. { ThreadWorkerTaskBase tw = (ThreadWorkerTaskBase)queuedTasks[task.TaskID]; tw.WorkerThread = Thread.CurrentThread; } RaiseBackroundTasksRunning(queuedTasks.Count); try { LocalRunProcess(); } finally { queuedTasks.Remove(task.TaskID); RaiseBackroundTasksRunning(queuedTasks.Count); } }
public TaskResultInfo(ThreadWorkerTaskBase task, ThreadWorkerProgressArgs args) { this.Task = task; this.Args = args; }
public TaskStartInfo(StartMethod startMethod, ThreadWorkerTaskBase task, DuplicateTaskQueued action) { this.startMethod = startMethod; this.task = task; this.action = action; }
protected void RaiseBackgroundTaskFinished(ThreadWorkerTaskBase task, int total, int current, Exception error, object result) { ThreadWorkerProgressArgs args = new ThreadWorkerProgressArgs(task.TaskID, total, current, error, true, result); taskResultInfos.Enqueue(new TaskResultInfo(task, args)); }
/// <summary> /// Execute a task in synchronized manner. /// </summary> /// <param name="task">Task to start</param> /// <returns>An Exception object on any failure within the task, /// or null if the task was successfully finished or cancelled.</returns> public static Exception RunTaskSynchronized(ThreadWorkerTaskBase task) { return(RunTaskSynchronized(task, DuplicateTaskQueued.Ignore)); }
/// <summary> /// Queue a task using a freshly created Thread. If the same task is yet running, /// the call will wait for the first one to finish work (DuplicateTaskQueued.Wait). /// </summary> /// <param name="task">Task to start</param> /// <returns>True, if the task was successfully started, else false.</returns> public static bool StartTask(ThreadWorkerTaskBase task) { return(StartTask(task, DuplicateTaskQueued.Ignore)); }
/// <summary> /// Constructor called by callee using ThreadPool OR ThreadStart /// </summary> /// <param name="task">ThreadWorkerTaskBase</param> public ThreadWorkerBase(ThreadWorkerTaskBase task) { this.task = task; }
/// <summary> /// Have to be overridden to impl. the real work a background task /// have to fulfill /// </summary> /// <param name="task"></param> protected virtual Exception DoTaskWork(ThreadWorkerTaskBase task) { return(new NotImplementedException("Inherit the class and override DoTaskWork() to work on tasks in background")); }
/// <summary> /// The worker method. /// </summary> /// <param name="task"></param> protected override Exception DoTaskWork(ThreadWorkerTaskBase task) { //if ((Task)task.TaskID == Task.AnonymousDelegate) //{ // Action action = (Action)task.Arguments[0]; // if (action == null) // throw new InvalidOperationException("no Action delegate specified"); // action(); // // default event if no result(s) from processing: // RaiseBackgroundTaskFinished(task, 1, 1, null, null); // return null; //} RssBanditApplication app = ((ThreadWorkerTask)task).Application; int maxTasks = 0, currentTask = 0; bool force; UltraTreeNode feedNode; string stylesheet, html; switch ((Task)task.TaskID) { case Task.LoadAllFeedSourcesSubscriptions: List <FeedSourceEntry> entries = (List <FeedSourceEntry>)task.Arguments[0]; var finished = new ManualResetEvent(false); int max = entries.Count; int current = 0; for (int i = 0; i < max; i++) { IndexedFeedSourceEntry e = new IndexedFeedSourceEntry(entries[i], i); PriorityThreadPool.QueueUserWorkItem( delegate(object state) { IndexedFeedSourceEntry fs = (IndexedFeedSourceEntry)state; int threadCurrent = fs.Index + 1; try { app.LoadFeedSourceSubscriptions(fs.Entry, true); this.RaiseBackroundTaskProgress(task, max, threadCurrent, null, fs.Entry); } catch (Exception loadEx) { this.RaiseBackroundTaskProgress(task, max, threadCurrent, loadEx, fs.Entry); } finally { if (Interlocked.Increment(ref current) >= max) { if (finished != null) { finished.Set(); } } } }, e, 1); } if (max > 0) { finished.WaitOne(Timeout.Infinite, true); } break; case Task.LoadFeedSourceSubscriptions: app.LoadFeedSourceSubscriptions((FeedSourceEntry)task.Arguments[0], true); break; // code mocved to FlaggedItemsFeed migrate method: //case Task.LoadSpecialFeeds: // app.InitializeFlaggedItems(); // break; case Task.RefreshFeeds: force = (bool)task.Arguments[0]; app.FeedSources.ForEach(s => s.RefreshFeeds(force)); break; case Task.RefreshCommentFeeds: force = (bool)task.Arguments[0]; app.CommentFeedsHandler.RefreshFeeds(force); break; case Task.RefreshCategoryFeeds: FeedSourceEntry entry = (FeedSourceEntry)task.Arguments[0]; string category = (string)task.Arguments[1]; force = (bool)task.Arguments[2]; entry.Source.RefreshFeeds(category, force); break; case Task.LoadCommentFeed: INewsItem item = (INewsItem)task.Arguments[0]; if (item == null) { throw new InvalidOperationException("Non-Null task argument 'item' expected."); } object result = null; if ((item.Feed != null) && (item.Feed.owner is IFacebookFeedSource)) { IFacebookFeedSource fbSource = item.Feed.owner as IFacebookFeedSource; result = fbSource.GetCommentsForItem(item); } else { NewsFeed cmtFeed = new NewsFeed(); cmtFeed.link = item.CommentRssUrl; cmtFeed.title = item.Feed.title; if (!string.IsNullOrEmpty(item.Feed.authUser)) { // take over credential settings string u = null, p = null; FeedSource.GetFeedCredentials(item.Feed, ref u, ref p); FeedSource.SetFeedCredentials(cmtFeed, u, p); } result = RssParser.DownloadItemsFromFeed(cmtFeed, app.Proxy, FeedSource.Offline); } RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, new object[] { result, item, task.Arguments[1], task.Arguments[2] }); return(null); case Task.TransformFeed: IFeedDetails feed = (IFeedDetails)task.Arguments[0]; feedNode = (UltraTreeNode)task.Arguments[1]; stylesheet = (string)task.Arguments[2]; html = app.FormatFeed(stylesheet, feed); RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, new object[] { feedNode, html }); return(null); case Task.TransformCategory: FeedInfoList feeds = (FeedInfoList)task.Arguments[0]; feedNode = (UltraTreeNode)task.Arguments[1]; stylesheet = (string)task.Arguments[2]; html = app.FormatFeeds(stylesheet, feeds); RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, new object[] { feedNode, html }); return(null); default: throw new InvalidOperationException("Unhandled ThreadWorker Task: " + task.TaskID); } // default event if no result(s) from processing: RaiseBackgroundTaskFinished(task, maxTasks, currentTask, null, null); return(null); }