惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MyScale Blog
MyScale Blog
Jina AI
Jina AI
爱范儿
爱范儿
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
Intezer
The Cloudflare Blog
T
Threat Research - Cisco Blogs
G
Google Developers Blog
Stack Overflow Blog
Stack Overflow Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Docker
AI
AI
Scott Helme
Scott Helme
Attack and Defense Labs
Attack and Defense Labs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LangChain Blog
Recent Announcements
Recent Announcements
Security Latest
Security Latest
Hugging Face - Blog
Hugging Face - Blog
W
WeLiveSecurity
Last Week in AI
Last Week in AI
Security Archives - TechRepublic
Security Archives - TechRepublic
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
S
Securelist
S
Security Affairs
Project Zero
Project Zero
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
T
Tor Project blog
A
About on SuperTechFans
V2EX - 技术
V2EX - 技术
宝玉的分享
宝玉的分享
T
Tenable Blog
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
Simon Willison's Weblog
Simon Willison's Weblog
Forbes - Security
Forbes - Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
V
V2EX
AWS News Blog
AWS News Blog
The GitHub Blog
The GitHub Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Privacy & Cybersecurity Law Blog
阮一峰的网络日志
阮一峰的网络日志
I
InfoQ
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Hacker News: Front Page
美团技术团队

博客园 - 冷风.net

以OO的思想利用JS來實現五子棋 開放幾個原來寫的js代碼,供大家娛樂一下 使用JS寫的第一個游戲[俄羅斯方塊] 假如現在讓你去說服客戶使用asp.net2.0開發系統,你會怎麼說服呢? 對象化javascript日期控件 - 冷风.net - 博客园 防止圖片在WEB頁面上下載 - 冷风.net - 博客园 今天從新整理的大小寫數據轉換 - 冷风.net - 博客园 常用的XPATH說明 XmlHttp在DoNet中的完全应用---前/后台完成分离篇 系统用户权限与角色分析 学习设计模式之Composite 模式 改進Richer的WEB頁面進度條! 学习设计模式之Bridge模式 学习设计模式之生成器(Builder Pattern)模式 再谈Abstract Factory模式来实现数据库操作的类 Factory Method来实现数据库操作的类 不周表結構合併問題 今天下午困惑的問題,終於TMD搞出來了 利用線程實現錠時執行的運行模型
工作排程
冷风.net · 2005-09-10 · via 博客园 - 冷风.net

最近在一個專案中因客戶要求數據能夠自行導入導出,本來這個是准務用SQL那個自帶的排程的,但TMD客戶不要,要求一定在WEB上可以設置,啟動。這不郁悶,得靠自己寫了,開始在網上找這方面的資料,TNND不知咱搞的沒找到氣憤(大概是我不會找資料吧,沒讀過研,哈哈自我安慰下);
經過幾天的瞎忙,終於完成了,自己也試了下可以運行,速度應在自己機子上試的沒感覺,哈哈
至少導入導出這裡就不說了,那個相信都家都玩過,這幾天想的排程有兩種方案可以實現,具體不知道對不對,反正是自己瞎搞的,如有知道windows的那個排程或sql的那個排程是怎樣實現的或有做過這方面的例子的
歡迎一起討論:
方案一:
  1. 其排程的XML檔

 2. 排程的類文件
  

using System;
using System.Xml;
using System.Threading;
using System.Reflection;


namespace DBEntryTest
{
    
/// <summary>
    
/// 排程
    
/// </summary>

    public class Assignment
    
{
        
private XmlDocument xmlDoc;
        
private delegate void myMothod(XmlNode node);
        
        
public Assignment()
        
{
            xmlDoc 
= new XmlDocument();
        }


        
#region    排程Xml文件
        
private String fileSource = String.Empty;
        
/// <summary>
        
/// 排程Xml文件
        
/// </summary>

        public String FileSource
        
{
            
get{return fileSource;}
            
set{fileSource = value;}
        }

        
#endregion


        
#region 啟動排程
        
/// <summary>
        
///  啟動排程
        
/// </summary>

        public void Run()
        
{
            
if(this.FileSource.Equals(String.Empty))
                
throw new Exception("請指定排程Xml文件源!");
            
this.xmlDoc.Load(this.FileSource);
            
//獲取所有的排程信息
            XmlNodeList nodeList = xmlDoc.SelectNodes("//Assignments/Assignment");
            
if(nodeList.Count > 0)
            
{
                
foreach(XmlNode node in nodeList)
                
{
                    
//每條線程執行一個排程
                    ThreadPool.QueueUserWorkItem(new WaitCallback(SingleAssignment),node);
                }

            }

        }

        
#endregion


        
#region 單排程

        
#region 單排程啟始接口
        
/// <summary>
        
/// 單排程啟始接口
        
/// </summary>
        
/// <param name="args">排程信息</param>

        private void SingleAssignment(object args)
        
{
            XmlNode node 
=(XmlNode)args;
            
string type = node.Attributes["typeName"].Value;
            
switch(type)
            
{
                
case "Month":
                    ListenerMonth(node);
                    
break;
                
case "Week":
                    ListenerWeek(node);
                    
break;
                
case "Day":
                    ListenerDay(node);
                    
break;
                
default:
                    
break;
            }

        }

        
#endregion


        
#region 監聽月
        
/// <summary>
        
/// 監聽月
        
/// </summary>
        
/// <param name="node">排程信息</param>

        private void ListenerMonth(XmlNode node)
        
{
            XmlNode subNode 
= node.SelectSingleNode("./Months/Month[@id=\"" + DateTime.Now.Month.ToString() + "\"]");
            
if(subNode != null )
            
{
                
//當前月為執行月
                string type = subNode.Attributes["typeName"].Value;
                
switch(type)
                
{
                    
case "Week":
                        ListenerWeek(node);
                        
break;
                    
case "Day":
                        ListenerDay(node);
                        
break;
                    
default:
                        
throw new Exception("按月執行的類型不正確!");
                }

            }

            
else
            
{
                Thread.Sleep(DateTime.Now.AddMonths(
1).AddDays(-DateTime.Now.Day).AddHours(-DateTime.Now.Hour).AddMinutes(-DateTime.Now.Minute) - DateTime.Now);
                ListenerMonth(node);
            }

        }

        
#endregion


        
#region 監聽周
        
/// <summary>
        
/// 監聽周
        
/// </summary>
        
/// <param name="node">排程信息</param>

        private void ListenerWeek(XmlNode node)
        
{
            XmlNodeList nodeList 
= node.SelectNodes("./Weeks/Week[@id=0]");
            
if(nodeList.Count > 0)
            
{
                
bool isToday = false;    //是否今天執行
                foreach(XmlNode dayNode in nodeList)
                
{
                    
if(dayNode.SelectSingleNode("./Day[@id=" + WeekValue(DateTime.Now.DayOfWeek).ToString() + "]"!= null)
                    
{
                        isToday 
= true;
                        
break;
                    }

                }

                
if(isToday)
                
{
                    myMothod delegate1 
= new myMothod(ListenerWeek);
                    ListenerHour(node,delegate1);
                }

                
else
                
{
                    
//等待下一天
                    Thread.Sleep(DateTime.Now.AddDays(1).AddHours(-DateTime.Now.Hour).AddMinutes(-DateTime.Now.Minute) - DateTime.Now);
                    
if(GetLastDateInMonth(DateTime.Now.Year,DateTime.Now.Month).Equals(DateTime.Now.Day))
                    
{
                        
if(node.Attributes["type"].Value.Equals("Month"))
                        
{
                            ListenerMonth(node); 
//如為按月執行,則返回監聽月
                        }

                        
else
                        
{
                            ListenerWeek(node);    
//繼續
                        }

                    }

                    
else
                    
{
                        ListenerWeek(node);    
//繼續
                    }

                }

            }

        }

        
#endregion


        
#region 監聽天
        
/// <summary>
        
/// 監聽天
        
/// </summary>
        
/// <param name="node">排程信息</param>

        private void ListenerDay(XmlNode node)
        
{
            
string lastDate =  (GetLastDateInMonth(DateTime.Now.Year,DateTime.Now.Month).Equals(DateTime.Now.Day)) ? "0" : "32";
            
if(node.SelectSingleNode("./Days/Day[@id=" + DateTime.Now.Day + " or @id=" + lastDate + "]"!= null)
            
{
                
//為今天執行
                myMothod delegate1 = new myMothod(ListenerDay);
                ListenerHour(node,delegate1);
            }

            
else
            
{
                
//等待下一天
                Thread.Sleep(DateTime.Now.AddDays(1).AddHours(-DateTime.Now.Hour).AddMinutes(-DateTime.Now.Minute) - DateTime.Now);
                
if(GetLastDateInMonth(DateTime.Now.Year,DateTime.Now.Month).Equals(DateTime.Now.Day))
                
{
                    
if(node.Attributes["type"].Value.Equals("Month"))
                    
{
                        ListenerMonth(node); 
//如為按月執行,則返回監聽月
                    }

                    
else
                    
{
                        ListenerDay(node);    
//繼續
                    }

                }

                
else
                
{
                    ListenerDay(node);    
//繼續
                }

            }

        }

        
#endregion


        
#region 監聽小時
        
/// <summary>
        
/// 監聽小時
        
/// </summary>
        
/// <param name="node">排程信息</param>

        private void ListenerHour(XmlNode node, myMothod delegate1)
        
{
            
if(node.SelectSingleNode("./Hours/Hour[@id=" + DateTime.Now.Hour.ToString() + "]"!= null)
            
{
                
//當前小時
                ListenerMinute(node,delegate1);
            }

            
else
            
{
                Thread.Sleep(DateTime.Now.AddHours(
1).AddMinutes(-DateTime.Now.Minute) - DateTime.Now);//等待下一小時
                if(DateTime.Now.Hour == 0)
                
{
                    delegate1(node);
                }

                
else
                
{
                    ListenerHour(node,delegate1);
                }

            }

        }

        
#endregion


        
#region 監聽分鐘
        
/// <summary>
        
/// 監聽分鐘
        
/// </summary>
        
/// <param name="node">排程信息</param>

        private void  ListenerMinute(XmlNode node, myMothod delegate1)
        
{
            
if(node.SelectSingleNode("./Minutes/Minute[@id=" + DateTime.Now.Minute.ToString() + "]"!= null)
            
{
                
//當前分鐘
                string execute = node.Attributes["execute"].Value;    //取得執行方法
                #region 取得排程的其它信息

                
#endregion


                
//執行方法可能需要較長的時間,所在采用拋出線程的方法來異步執行
                ExecuteParam executeParam = new ExecuteParam(execute,null);
                ThreadPool.QueueUserWorkItem(
new WaitCallback(Execute),executeParam);
            }


            Thread.Sleep((
60 - DateTime.Now.Second) * 60 );    //等待下一分鐘
            if(DateTime.Now.Minute == 0)
            
{
                
//返回監聽小時
                ListenerHour(node,delegate1);
            }

            
else
            
{
                ListenerMinute(node,delegate1);
            }

        }

        
#endregion


        
#endregion


        
#region 執行排程操作
        
/// <summary>
        
/// 執行排程操作
        
/// </summary>

        private void Execute(object args)
        
{
            ExecuteParam exeArgs 
= (ExecuteParam)args;
            
string exeObj = exeArgs.ExeObj;
            
string className = exeObj.Substring(0,exeObj.LastIndexOf("."));
            
string methodName = exeObj.Substring(exeObj.LastIndexOf(".")+1).Replace("()","");
            Type type 
= Type.GetType(className);
            MethodInfo method 
= type.GetMethod(methodName);
            method.Invoke(
null,exeArgs.Argument);
        }

        
#endregion


        
#region 執行排程操作參數
        
/// <summary>
        
///  執行排程操作參數
        
/// </summary>

        private struct ExecuteParam
        
{
            
private string exeObj;
            
private object[] argument;

            
public ExecuteParam(string argument1,object[] argument2)
            
{
                
this.exeObj = argument1;
                
this.argument = argument2;
            }


            
/// <summary>
            
/// 執行個體,如:EArtService.Output.OutputXml()
            
/// </summary>

            public string ExeObj
            
{
                
get{return this.exeObj;}
            }

            
/// <summary>
            
/// 執行個體參數
            
/// </summary>

            public object[] Argument
            
{
                
get{return this.argument;}
            }

        }

        
#endregion



        
#region 取得星期的序號
        
/// <summary>
        
/// 取得星期的序號
        
/// </summary>
        
/// <param name="week"></param>
        
/// <returns></returns>

        public int WeekValue(DayOfWeek week)
        
{
            
int iWeek = 0;
            
switch(week)
            
{
                
case DayOfWeek.Monday:
                    iWeek 
= 1;
                    
break;
                
case DayOfWeek.Tuesday:
                    iWeek 
= 2;
                    
break;
                
case DayOfWeek.Wednesday:
                    iWeek 
= 3;
                    
break;
                
case DayOfWeek.Thursday:
                    iWeek 
= 4;
                    
break;
                
case DayOfWeek.Friday:
                    iWeek 
= 5;
                    
break;
                
case DayOfWeek.Saturday:
                    iWeek 
= 6;
                    
break;
                
case DayOfWeek.Sunday:
                    iWeek 
= 7;
                    
break;
                
default:
                    iWeek 
= 0;
                    
break;
            }

            
return iWeek;
        }

        
#endregion


        
#region 取得這個月的最後一天
        
/// <summary>
        
/// 取得這個月的最後一天
        
/// </summary>
        
/// <param name="month"></param>
        
/// <returns></returns>

        private int GetLastDateInMonth(int year,int month)
        
{
            
int reValue = 30;
            
if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12)
            
{
                reValue 
= 31;
            }

            
if(month==2)
            
{
                reValue 
= 28;
                
if((year/4==0 && year/100==0|| year/400==0)
                
{
                    reValue 
= 29;
                }

            }

            
return reValue;
        }

        
#endregion

        
    }

}

以上代碼就不明細說明瞭,上面的注解我想說得差不多可以理解了吧

這個排程的工作原理,有點例似於Socket的監聽吧,所以我叫它監聽排程
所用到的技術(委託,線程,反射)

 3. 工作流程圖

方案二
   因那個專案客戶還沒驗收,等驗收後再拿來羨丑了(工作原理:只是多了個按下次執行日期來算的)

 
   哪位感興趣的朋友,如了解排程算法的可以一起研究下,最好是教我:)O