怎么樣把大象塞進冰箱里?
分3步:打開冰箱門、把大象塞進去、關上冰箱門。
怎么樣讓 SharePoint 2010 定時做件事情呢?
Something 函數
這次不關心是具體做什么事情,因為我可以把這件事情看成是:void Something(string content); 只要讓 SharePoint 2010 給我一個機會,定時的調用這個 Something 函數就可以了,剩下的這個函數會處理。
Time Job
Time Job 可以在服務器后台定期執行 Something 並且可以無視登錄 SharePoint 的用戶身份來以最大權限執行任務。(沒有用戶登錄 SharePoint 也不影響 Time Job 的運行,它就在那里自己跑着。)同時,如你所擔心的,代價就是 Time Job 的開發需要服務器場部署。
- 創建一個空白的服務器場解決方案
- 添加一個繼承 SPJobDefinition 的類,用做調度任務的主程序(Something 函數)
- 添加一個繼承 SPPersistedObject 的類,用於保存調度任務主程序的設置信息
- 在 Feature 的激活事件里面創建 SPJobDefinition 派生類的實例、SP%Schedule 類(% 可以是 Hourly、Daily、Weekly 等等定時間隔)、設置信息的派生類
- 部署、測試
具體的代碼可以參考:Creating Timer Jobs in SharePoint 2010 that Target Specific Services
這里有個問題:SP%Schedule 類只有分鍾、小時、天、周、月、年的間隔,如果我希望每個工作日的上午 9 點 25 分執行一個操作,怎么辦? 如果不考慮與其它技術方案配合,只用 Time Job,那么可能需要這樣:
- 利用 SPDailySchedule 類在 Feature 的激活事件里面設置按天調用
- SPDailySchedule 設置 BeginHour, BeginMinute 為 9 和 20 (提前一點),EndHour, EndMinute 為 9 和 30(給 Time Job Service 一點兒時間)
- 在 SPJobDefinition 子類(干活的那個)里先判斷當前系統日期,看看是否是工作日(但是,如果考慮春節、中秋這種假日,你就不能只用 Time Job 了),是的話,調用 Something
Time Job 的調用時有延遲的。不是你說讓它 9 點 25 分開始,它就能夠開始的。它會盡力,但事實上,那個 Time Job Service 相當的忙,哪怕你的 SharePoint 環境是剛剛安裝好的,什么都沒做,它也已經在后台開始“瘋狂”的運行了。
依靠 Time Job 的其它定時調度程序(如 User Profile 同步、工作流)也都會有延遲。而且,服務器場的解決方案部署,是要重啟 IIS 的,調試的時候頗為痛苦。
然而,很多時候,當提到要打開冰箱門把大象放進去,一般腦海里面首先還是會閃過 Time Job 的影子。“調度任務扔進去就可以不管”、“擁有各種權限”就是它的優勢。
工作流
這本質上還是在用 Time Job。不過,部署更加靈活,不必一定要用服務器場部署。
SharePoint Designer 工作流
利用 SharePoint Designer 設置工作流等待一段特定的時間后執行某個操作,比如下面這個每周四下午 3 點多執行的工作流:
里面的 Pause until 日期也可以寫在列表項的一個日期字段里面,用戶可以指定暫停的時間。
這樣需要執行多少次就寫多少個 “Pause”的做法,只適用於少量的定時調用,量大的時候,肯定是 Hold 不住的。而且,大量這種 long running 的工作流(實例)拖死服務器那是相當容易的事情。
而且,調度間隔不可能太短(通常建議 5 分鍾),因為 Time Job 那里,給 Workflow 的事件做處理的間隔默認也是 5 分鍾:
有沒有辦法讓工作流自己重新開始執行自己,實現不限次數的定時呢?
答案是:沒有。
那是否可能讓工作流在創建列表項時自動啟動,然后在工作流里面定時再新建一個列表項,從而實現循環觸發呢?
答案是:不行。SharePoint 里面列表自己通過工作流創建在自己內部的列表項根本不觸發工作流。
那我兩個列表互相觸發還不行?
答案是:不行。第一波觸發可以完成,第二波就會“失敗”,工作流根本就觸發。微軟知道你想干什么,它 say no 了。
那用工作流能定時做什么?!
答案:它可以和列表項、信息策略配合使用。
為什么要這么麻煩?!
答案:因為在生產環境,你很可能根本碰不到 SharePoint 服務器,別提 Farm Admin 了,可能 Site Collection Admin 都沒有。必須利用手頭能用的資源。
信息策略
通過配置 Retention 策略,可以讓指定的工作流定期執行,比如每隔 5 天調用一次我們的工作流:
此時,我們把工作流當作 Something 函數用。(知道為什么一開始我就沒寫 Something 函數代碼了吧,因為,它可能根本就不是一段代碼)
不過,要注意一點:信息策略后台仍然是 Time Job 在跑,所以,Time Job 的執行周期要特別留意(因為默認是每周,這樣,你每 5 天最后也還是變成每周):
列表項
或者說,“定時列表”項。
前面幾種方法,有個問題。比如這種應用:每個月的第一周、第三周的周二下午3點開部門會議。前面幾種做法就沒戲了。不是每個月都有4周的,這個會開不了幾次,定時就偏了。
此時,回到我們的工作流 Pause until 上面來。
我們不是說,可以在列表項里面加入日期字段作為工作流等待的到期日期么?那么,呵呵,剛才的部門會議應用,你就可以先建好 1 年(24 次)的列表項,然后每個列表項的“會議日期”字段值設置為當期的准確日期,配合工作流即可實現定時。非常准確,完全不受閏年、5周的月份的影響 :)
Alert 通知
如果這個 Something 恰好是匯總某個列表的內容改動,發郵件給經理。那么用 Alert 功能就最合適不過了:
寫代理程序
用 Visual Studio 拖一個 Form 程序(WPS 也可以)、掛一個 Timer 控件,調 SharePoint Client Object Model 模型,直接 do Something。
想怎么寫就怎么寫,什么節假日、公司假日、工廠 Shutdown 的假日、每月第幾周周一的大會,風雨無阻,全部都可以考慮進去。而且,還不用 Time Job,特別節省資源。
只要跑在一台不關機的電腦上就可以,掛在那里跑就行。(管理員還是要定期去看看的,不如代理自己掛了就不好了)
只有一個問題:用戶身份驗證。畢竟是 Client Object Model,萬一運氣不好(很有可能),SharePoint 搞了 SAML 玩 Federation,你得折騰一番了。
用手
你上好鬧鍾,坐在電腦旁邊。
每次時間到了,就打開 SharePoint Site,然后進去點擊幾個按鈕執行任務。
我可以 100% 的確認:這次絕對可以把大象裝進冰箱里面。