/// 任务准备就绪(等待开始) public void ReadyToStart() { if (m_State != cGlobalParas.TaskState.Started && m_State != cGlobalParas.TaskState.Completed) { State = cGlobalParas.TaskState.Waiting; } }
/// 停止任务 public void Stop() { m_ThreadsRunning = false; foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) { dtc.Stop(); } //开始检测是否所有线程都以完成或退出 bool isStop = false; while (!isStop) { isStop = true; foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) { //if (dtc.WorkThread.ThreadState == cGlobalParas.GatherThreadState.Started && dtc.WorkThread.IsAlive ) if (dtc.IsStop == false) { isStop = false; } } Thread.Sleep(200); } State = cGlobalParas.TaskState.Stopped; }
/// <summary> /// /// </summary> /// <param name="old_state">旧的状态</param> /// <param name="new_statue">新的状态</param> public TaskStateChangedEventArgs(Int64 TaskID, cGlobalParas.TaskState oldState, cGlobalParas.TaskState newState) { //m_TaskID = TaskID; base.TaskID = TaskID; m_OldState = oldState; m_NewState = newState; }
/// 处理 分解采集任务 错误事件 private void TaskThreadError(object sender, TaskThreadErrorEventArgs e) { //当采集发生错误后,系统首先需要检测当前是否连接网络 //如果没有连接网络,即无Internet,则系统停止此任务执行 if (cTool.IsLinkInternet() == false) { Stop(); m_State = cGlobalParas.TaskState.Failed; if (e_TaskFailed != null) { e_TaskFailed(this, new cTaskEventArgs(TaskID, TaskName, false)); } return; } cGatherTaskSplit gt = (cGatherTaskSplit)sender; //如果出错调用此事件,也表示完成了一个网址的采集,但是出错了 //一个线程发生错误并不允许停止整个任务执行,即便所有线程都发生促务 //也需要保障任务执行,只是把任务出错信息写入日志 //if (gt.ErrorCount >= cGatherManage.MaxErrorCount) //{ // 达到最大错误数,停止当前线程 //bool failed = true; // 如果当前任务所有的线程都停止了,则判断为任务失败 //foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) //{ // if (!gt.Equals(dtc) && dtc.IsThreadAlive) // { // failed = false; // break; // } //} //if (failed) //{ // State = cGlobalParas.TaskState.Failed; // return; //} //} if (e_TaskError != null) { e_TaskError(this, new TaskErrorEventArgs(gt, e.Error)); } //} }
//停止任务,此停止任务与Stop不同的是,强制停止所有工作线程 //Stop是属于执行完一个完整工作后停止,而Abort不论是否执行到 //何种状态,必须强制停止,此种方式会导致数据丢失 /// 取消任务(移除任务) public void Abort() { m_ThreadsRunning = false; foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) { dtc.Abort(); } State = cGlobalParas.TaskState.Aborted; }
/// 启动所有采集任务线程 如果没有分解任务,则启动的单个线程进行采集 private void StartAll() { foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) { dtc.TaskSplitData.TrueUrlCount = dtc.TaskSplitData.UrlCount; dtc.TaskSplitData.GatheredUrlCount = 0; dtc.TaskSplitData.GatheredTrueUrlCount = 0; dtc.TaskSplitData.GatheredErrUrlCount = 0; dtc.TaskSplitData.GatheredTrueErrUrlCount = 0; dtc.Start(); } State = cGlobalParas.TaskState.Started; }
/// 初始化采集任务对象,并根据任务数据确定此任务是否 /// 由多个线程来完成,如果是,则进行任务分解 internal cGatherTask(cGatherManage taskManage, cTaskData taskData) { m_TaskManage = taskManage; m_TaskData = taskData; m_State = TaskData.TaskState; m_list_GatherTaskSplit = new List <cGatherTaskSplit>(); //当任务数据传进来之后,直接对当前任务进行任务分解, //是否需要多线程进行,并初始化相关数据内容 SplitTask(); //开始初始化任务 TaskInit(); }
/// 重置任务为未初始化状态 internal void ResetTaskState() { e_TaskCompleted = null; e_TaskStarted = null; e_TaskError = null; e_TaskStateChanged = null; e_TaskStopped = null; e_TaskFailed = null; e_TaskAborted = null; e_TaskThreadInitialized = null; this.State = cGlobalParas.TaskState.UnStart; m_IsInitialized = false; e_Log = null; e_GData = null; }
//此方法专用于修改taskrun.xml中采集的数值使用,其他情况均不可使用 //此方法不通用,当前对xml操作类设计有问题,此类需要重新设计 //同时需要更新Urlcount,也许此数值不是很准确,但当采集任务更新是,会进行刷新 public void EditTaskrunValue(string TaskID, cGlobalParas.TaskState tState, string GUrlCount, string GTrueUrlCount, string GErrUrlCount, string GTrueErrUrlCount, string TrueUrlCount) { XmlNodeList fathernode = objXmlDoc.GetElementsByTagName("Tasks"); XmlNodeList nodes = fathernode[0].ChildNodes; for (int i = 0; i < nodes.Count; i++) { for (int j = 0; j < nodes[i].ChildNodes.Count; j++) { //for (int m=0; if (nodes[i].ChildNodes[j].Name == "TaskID" && nodes[i].ChildNodes[j].InnerText == TaskID) { XmlNode nod = nodes[i].SelectSingleNode("TaskState"); nod.InnerText = ((int)tState).ToString(); nod = null; nod = nodes[i].SelectSingleNode("TrueUrlCount"); nod.InnerText = TrueUrlCount; nod = null; nod = nodes[i].SelectSingleNode("GatheredUrlCount"); nod.InnerText = GUrlCount; nod = null; nod = nodes[i].SelectSingleNode("GatheredTrueUrlCount"); nod.InnerText = GTrueUrlCount; nod = null; nod = nodes[i].SelectSingleNode("ErrUrlCount"); nod.InnerText = GErrUrlCount; nod = null; nod = nodes[i].SelectSingleNode("TrueErrUrlCount"); nod.InnerText = GTrueErrUrlCount; nod = null; return; } } } }
/// 当某个线程采集完成后,会调用任务完成事件进行检测,如果任务完成则触发任务 /// 完成事件。但在此判断时需要注意,如果任务采集失败的数量和采集数量相等,则判断 /// 任务失败。且每次调用此事件时,都需要做一次检测,对每个子线程都检测一遍,看是否 /// 存在已经完成,但未触发完成事件的自线程。 private void onTaskCompleted() { if (m_TaskData.UrlCount == (m_TaskData.GatheredUrlCount + m_TaskData.GatherErrUrlCount) && m_State != cGlobalParas.TaskState.Completed) { if (m_TaskData.TrueUrlCount == m_TaskData.GatherErrUrlCount) { //如果全部采集都发生了错误,则此任务为失败 State = cGlobalParas.TaskState.Failed; } else { // 设置为完成状态,触发任务完成事件 State = cGlobalParas.TaskState.Completed; } //无论失败还是成功都要进行触发器的触发 if (m_TaskData.IsTrigger == true && m_TaskData.TriggerType == ((int)cGlobalParas.TriggerType.GatheredRun).ToString()) { cRunTask rt = new cRunTask(); rt.RunSoukeyTaskEvent += this.onRunSoukeyTask; cTaskPlan p; for (int i = 0; i < m_TaskData.TriggerTask.Count; i++) { p = new cTaskPlan(); p.RunTaskType = m_TaskData.TriggerTask[i].RunTaskType; p.RunTaskName = m_TaskData.TriggerTask[i].RunTaskName; p.RunTaskPara = m_TaskData.TriggerTask[i].RunTaskPara; rt.AddTask(p); } rt.RunSoukeyTaskEvent -= this.onRunSoukeyTask; rt = null; } } }
/// <summary> /// /// </summary> /// <param name="old_state">�ɵ�״̬</param> /// <param name="new_statue">�µ�״̬</param> public TaskStateChangedEventArgs(Int64 TaskID, cGlobalParas.TaskState oldState, cGlobalParas.TaskState newState) { //m_TaskID = TaskID; base.TaskID = TaskID; m_OldState = oldState; m_NewState = newState; }
/// 初始化采集任务线程 private void TaskInit() { string sPath = m_TaskData.SavePath + "\\" + m_TaskData.TaskName + "_file"; ///任务初始化分为两种情况,一种是未启动执行的任务,一种是已经启动但未执行完毕的任务 /// //m_TaskData.GatheredUrlCount = 0; //m_TaskData.GatherErrUrlCount = 0; //m_TaskData.TrueUrlCount = m_TaskData.UrlCount; if (!m_IsDataInitialized) { if (m_list_GatherTaskSplit.Count > 0) { // 清理可能存在的子线程 foreach (cGatherTaskSplit dtc in m_list_GatherTaskSplit) { dtc.Stop(); } m_list_GatherTaskSplit.Clear(); } if (IsCompleted) { // 修改此采集任务的状态为已采集完成,设置为状态为已完成,需要出发事件 m_State = cGlobalParas.TaskState.Completed; //m_State = cGlobalParas.TaskState.Completed; //e_TaskCompleted(this, new cTaskEventArgs(m_TaskData.TaskID, false)); } else { cGatherTaskSplit dtc; if (m_TaskData.TaskSplitData.Count > 0) { foreach (cTaskSplitData configData in m_TaskData.TaskSplitData) { dtc = new cGatherTaskSplit(); dtc.TaskManage = m_TaskManage; dtc.TaskID = m_TaskData.TaskID; dtc.WebCode = m_TaskData.WebCode; dtc.IsUrlEncode = m_TaskData.IsUrlEncode; dtc.UrlEncode = m_TaskData.UrlEncode; dtc.Cookie = m_TaskData.Cookie; dtc.StartPos = m_TaskData.StartPos; dtc.EndPos = m_TaskData.EndPos; dtc.SavePath = sPath; dtc.AgainNumber = m_TaskData.GatherAgainNumber; dtc.Ignore404 = m_TaskData.IsIgnore404; dtc.IsErrorLog = m_TaskData.IsErrorLog; dtc.TaskSplitData = configData; m_list_GatherTaskSplit.Add(dtc); dtc = null; } } else { dtc = new cGatherTaskSplit(); dtc.TaskManage = m_TaskManage; dtc.TaskID = m_TaskData.TaskID; dtc.WebCode = m_TaskData.WebCode; dtc.IsUrlEncode = m_TaskData.IsUrlEncode; dtc.UrlEncode = m_TaskData.UrlEncode; dtc.Cookie = m_TaskData.Cookie; dtc.StartPos = m_TaskData.StartPos; dtc.EndPos = m_TaskData.EndPos; dtc.SavePath = sPath; dtc.AgainNumber = m_TaskData.GatherAgainNumber; dtc.Ignore404 = m_TaskData.IsIgnore404; dtc.IsErrorLog = m_TaskData.IsErrorLog; // 新任务,则新建子线程 m_list_GatherTaskSplit.Add(dtc); dtc = null; } foreach (cGatherTaskSplit TaskSplit in m_list_GatherTaskSplit) { // 初始化所有子线程 TaskEventInit(TaskSplit); } } m_IsDataInitialized = true; } }