// 内部初始化,调用WebServices类中的ApiQuery从Webapi读取数据 private static void InitDateInfo(int year, int month) { if (year < 1 || year > 9999 || month < 1 || month > 12) { throw new ArgumentOutOfRangeException(); // 参数错误 } initProgess = 0; //DateTime sampleDate = new DateTime(year, month, 1); months[storedMonthCount] = new DateMonth(year, month); // 存储月份索引 int maxDayInMonth = DateTime.DaysInMonth(year, month); // 当前月的天数 for (int i = 0; i < maxDayInMonth; i++) { // 仅在第一次加载时(MainForm还未Show)向外界通报进度信息 if (isFirstLoad) { initCurrentDay = i + 1; // 记录正在初始化的天数 initProgess = initCurrentDay * 100 / maxDayInMonth; // 记录初始化进度 } DateTime date = new DateTime(year, month, i + 1); dateInfosInMonth[storedMonthCount, i + 1] = WebServices.ApiQueryOnJuhe(date); // 查询黄历信息 Console.WriteLine(year.ToString() + "/" + month.ToString() + "/" + (i + 1).ToString()); } isFirstLoad = false; storedMonthCount++; }
// 分配ApiQuery任务中月份的优先级 private static void AssignPriority(DateMonth centralMonth) { int assignedMonthCount = 0; // 清空awaitingMonthsQueue awaitingMonthsQueue.Clear(); // 分配顺序:摆动数列,如centralMonth为2016.8,队列为:(2016.8), 2016.9, 2016.7, 2016.10, 2016.6 ... for (int i = 0, loopCount = 0; assignedMonthCount < MAXMONTHSTORAGE; loopCount++) { i = -i; if ((loopCount + 1) % 2 == 0) // 每隔一次待分配的月份加1 { i++; } DateMonth month = centralMonth.AddMonth(i); // 跳过已queried的月份 if (!queriedMonthList.Exists(var => var.Year == month.Year && var.Month == month.Month)) { awaitingMonthsQueue.Enqueue(month); // 加入队列 assignedMonthCount++; } } }
private static void CurrentShowingMonthChangedHandler(object o) { DateMonth newMonth = o as DateMonth; if (newMonth == null) { throw new ArgumentException(); } AssignPriority(newMonth); // 按当前月份为中心月份重新分配优先级 }
private static void NewMonthQueryRequestedHandler(object o) { DateMonth newMonth = o as DateMonth; if (newMonth == null) { throw new ArgumentException(); } // 将刚查询的月份加入queriedMonthList queriedMonthList.Add(newMonth); }
// 初始化 public static void Initialize(DateMonth currentShowingMonth) { queriedMonthList.Add(currentShowingMonth); // 添加本月到已查询的月份列表 // 事件布线 DynamicApiQueryQueue.NewMonthQueryRequested += new MyEventHandlerArgs(NewMonthQueryRequestedHandler); OnlineDateInfoDatabase.NewMonthQueried += new MyEventHandlerArgs(NewMonthQueriedHandler); MainForm.CurrentShowingMonthChanged += new MyEventHandlerArgs(CurrentShowingMonthChangedHandler); AssignPriority(currentShowingMonth); // 为边界范围内的所有月份分配优先级 DynamicApiQuery(); // 启动工作线程 isInitialized = true; isRunning = true; }
// 动态查询Api,核心方法 private static void DynamicApiQuery() { Task queryTask = Task.Factory.StartNew(delegate { Thread.Sleep(1000); // 每分配完一个月份后阻塞线程,防止占用大量带宽 if (awaitingMonthsQueue.Count > 0) { queryingMonth = awaitingMonthsQueue.Dequeue(); OnNewMonthQueryRequested(queryingMonth); // 请求查询api } else { throw new InvalidOperationException(); // 发生未知错误,队列中无元素 } }); }
private static void NewMonthQueryRequestedHandler(object o) { DateMonth newMonth = o as DateMonth; if (newMonth == null) { throw new ArgumentException(); } if (searchMonth(newMonth.Year, newMonth.Month) != -1) // 异常:指定月份的黄历信息已存在于数据库中 { // ignore } else { InitDateInfo(newMonth.Year, newMonth.Month); } OnNewMonthQueried(newMonth); }
private static void NewMonthQueriedHandler(object o) { DateMonth newMonth = o as DateMonth; if (newMonth == null) { throw new ArgumentException(); } // 重新启动DynamicApiQuery线程 if (awaitingMonthsQueue.Count != 0) { DynamicApiQuery(); } else { Console.WriteLine("DynamicApiQueryFinished!"); isRunning = false; } }
/// <summary> /// 比较两个DateMonth类型相距的月份数,返回正数说明this更大,否则anotherMonth更大 /// </summary> /// <param name="anotherMonth">待比较的月份</param> /// <returns></returns> public int Compare(DateMonth anotherMonth) { if (this.Year == anotherMonth.Year) { return(this.Month - anotherMonth.Month); } else if (this.Year - anotherMonth.Year == 1) { return(this.Month + (12 - anotherMonth.Month)); } else if (this.Year - anotherMonth.Year == -1) { return(-((12 - this.Month) + anotherMonth.Month)); } else if (this.Year - anotherMonth.Year > 1) { return((this.Year - anotherMonth.Year - 1) * 12 + this.Month + (12 - anotherMonth.Month)); } else { return(-(this.Year - anotherMonth.Year - 1) * 12 + -((12 - this.Month) + anotherMonth.Month)); } }
public static event MyEventHandlerArgs NewMonthQueried; // 新月份已查询事件,在DynamicApiQueryQueue和MainForm中被处理 private static void OnNewMonthQueried(DateMonth dateMonth) { NewMonthQueried?.Invoke(dateMonth); }
/// <summary> /// 比较该月份与另一月份相距的月份数,返回正数说明this更大,否则anotherMonth更大 /// </summary> /// <param name="year">年</param> /// <param name="month">月</param> /// <returns></returns> public int Compare(int year, int month) { DateMonth dateMonth = new DateMonth(year, month); return(Compare(dateMonth)); }