C#實現Windows後臺服務實例淺析

C#實現Windows後臺服務實例以前要明白的一些概念:所謂Windows後臺服務,即後臺自動運行的程序,通常隨操做系統啓動而啓動,在個人電腦 服務後應用程序 服務裏面能看到當前電腦的服務.通常而言,程序上用VC、C++寫Windows服務,可是我對這些語言不是很熟,通常編程用C#較多,因此就用C#語言寫了一個Windows服務.html

C#實現Windows後臺服務實例其實需求是這樣的,作那個報價系統的時候加入了發短信的功能,訂單處理完即將發貨的時候要發送短信都客戶手機上,公司內部員工處理訂單超時要自動發短信,羣發產品促銷信息到客戶手機上等,還有定時發送短信的需求,因此最後面決定把發短信的模塊獨立出來,之後還有什麼功能方便一塊兒調用,而最終選擇了採用Windows後臺服務.sql

C#實現Windows後臺服務實例其實Windows服務並很差作到通用,它並不能在用戶的界面顯示一些什麼信息等,它只是在後臺默默的處理一些事情,起着輔助的做用.那如何實現發送段信通用調用的接口呢?它們之間的信息又是如何來交互呢?數據庫!對,就是它存儲數據信息的.而數據庫都能很方便的訪問操做.把發送短信的後臺服務定時去訪問一個數據庫,而另外任何要發送短信的地方也訪問數據庫,並插入一條要發送的短信到表裏面,稍後Windows後臺服務訪問該表將此短信發送出去.這多是一個比較蠢的方法,但實現起來較簡單.數據庫

C#實現Windows後臺服務實例首先,因爲它是要安裝的,因此它運行的時候就須要一個安裝類Installer將服務安裝到計算機,新建一個後臺服務安裝類繼承自Installer,安裝初始化的時候是以容器進行安裝的,因此還要創建ServiceProcessInstaller和ServiceInstaller服務信息組件添加到容器安裝,在Installer類增長以下代碼:編程

private System.ComponentModel.IContainer components = null;  private System.ServiceProcess.ServiceProcessInstaller spInstaller;  private System.ServiceProcess.ServiceInstaller sInstaller;  private void InitializeComponent()  {  components = new System.ComponentModel.Container();   // 建立ServiceProcessInstaller對象和ServiceInstaller對象  this.spInstaller = new System.ServiceProcess.ServiceProcessInstaller();  this.sInstaller = new System.ServiceProcess.ServiceInstaller();   // 設定ServiceProcessInstaller對象的賬號、用戶名和密碼等信息  this.spInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;  this.spInstaller.Username = null;  this.spInstaller.Password = null;   // 設定服務名稱  this.sInstaller.ServiceName = "SendMessage";  sInstaller.DisplayName = "發送短信服務";  sInstaller.Description = "一個定時發送短信的服務";   // 設定服務的啓動方式  this.sInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;   this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.spInstaller, this.sInstaller });  } C#實現Windows後臺服務實例再添加一個服務類繼承自ServiceBase,咱們能夠重寫基類的OnStart、OnPause、OnStop、OnContinue等方法來實現咱們須要的功能並設置指定一些屬性.因爲是定事發送短信的服務,天然少不了Windows記時器,在OnStart事件裏咱們寫入服務日誌,並初始化記時器.api

private System.Timers.Timer time;  private static readonly string CurrentPath = Application.StartupPath + "\\";  protected override void OnStart(string[] args)  {  string path = CurrentPath + "Log\\start-stop.log";  FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write);  StreamWriter sw = new StreamWriter(fs);  sw.WriteLine("The Service is Starting On " + DateTime.Now.ToString());  sw.Flush();  sw.Close();  fs.Close();   time = new System.Timers.Timer(1000 * Convert.ToInt32(GetSettings("TimeSpan")));  time.Enabled = true;  time.Elapsed += this.TimeOut;  time.Start();  } C#實現Windows後臺服務實例實例化記時器類啓動後,將在指定時間間隔觸發Elapsed指定事件,如上GetSettings爲讀取我App.config文件裏一個配置節點(值爲30)的方法,因此上面將會每隔30秒調用TimeOut方法.而改方法就是咱們發短信的具體操做.代碼以下:服務器

private void TimeOut(object sender, EventArgs e)  {  try {  if (GetSettings("Enabled").ToLower() == "true")  {  SqlConnection con = new SqlConnection(GetSettings("ConnString"));  SqlCommand cmd = new SqlCommand("select [sysid],[admin_inner_code],[user_inner_code],[phone],[message],[sendtime] from [tbl_note_outbox]", con);  con.Open();  SqlDataReader rdr = cmd.ExecuteReader();  while (rdr.Read())  {  string phone = rdr["phone"].ToString();  string message = rdr["message"].ToString();  string sendtime = rdr["sendtime"].ToString();  System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("GB2312");  string url = string.Format("http://211.155.23.205/isapi.dll?SendSms&AgentID={0}&PassWord={1}&phone={2}&msg={3}&sendtime={4}", GetSettings("AgentID"), GetSettings("PassWord"), phone,System.Web.HttpUtility.UrlEncode( message,encoder), sendtime);  System.Net.WebClient wClient = new System.Net.WebClient();  string msg = System.Text.Encoding.Default.GetString(wClient.DownloadData(url));  wClient.Dispose();   //刪除已經發送成功的,並保存發送記錄  if (msg == "發送成功")  {  DateTime dtsend = sendtime == "0" ? DateTime.Now : DateTime.ParseExact(sendtime, "yyyyMMddHHmmss", null);  string sql = string.Format("delete from [tbl_note_outbox] where [sysid]={0} INSERT INTO [tbl_note_log] ([admin_inner_code],[user_inner_code],[status],[phone],[message],[sendtime]) VALUES('{1}','{2}','{3}','{4}','{5}','{6}')", rdr["sysid"], rdr["admin_inner_code"], rdr["user_inner_code"], msg, phone, message, dtsend);  SqlConnection conn = new SqlConnection(GetSettings("ConnString"));  SqlCommand delete = new SqlCommand(sql, conn);  conn.Open();  delete.ExecuteNonQuery();  conn.Close();  delete.Dispose();  }   }  rdr.Close();  con.Close();  cmd.Dispose();  }  }  catch (Exception ex)  {  string errorPath = CurrentPath + "Log\\error.log";  if (!File.Exists(errorPath))  {  FileStream create = File.Create(errorPath);  create.Close();  }  FileStream fs = new FileStream(errorPath, FileMode.Append, FileAccess.Write);  StreamWriter sw = new StreamWriter(fs);  sw.WriteLine("Exception: " +ex.Message+" --"+ DateTime.Now.ToString());  sw.Flush();  sw.Close();  fs.Close();  }   } C#實現Windows後臺服務實例上面咱們使用try、catch訪問數據庫,並記錄錯誤異常信息. 發送短信是使用發送一個Web請求發送出去的,要注意請求url字符串的編碼類型,要與請求頁面編碼一致,否則會出現亂碼.上面咱們請求的是智網通集團短信(網址:http://www.09168.net/)的Web接口,經過訪問他的網站來實現發短信,固然還要傳遞一些用戶名、密碼、手機號碼和要發送的短信息等參數.他的收費平均大概爲7分/條的樣子,其實我本來不想用發送Web請求的這樣方式來發送短信的,它自己提供了調用它發送短信的DLL,並且還有vc、delphi調用的Demo,可是沒有用C#調用的例子,我剛開始試着用非託管動態連接庫他提供的DLL,不知方法調用那裏出錯了一直都沒能成功發送出短信,因此後來就用了他的Web方式接口了.他頁面直接返回發送短信的狀態信息.返回發送成功則短信發送成功,成功後我再將此條信息從要發送短信表裏刪除並保存在發送記錄表裏面,以備往後方便查詢.其實登錄他的官網進入後臺也能方便的查詢,以下圖.ide

 

C#實現Windows後臺服務實例發送短信服務的代碼基本上搞定了,就看怎麼在服務器上安裝部署了.C#寫的Windows後臺服務不能直接安裝,須要藉助.NET Framework裏面的InstallUtil.exe安裝工具安裝,咱們能夠作成一個執行CMD命令的文件BAT文件來安裝啓動它,命令以下:工具

%windir%\Microsoft.NET\  Framework\v2.0.50727\  InstallUtil.exe %CD%\  SendMessage.exe  net start SendMessage 學習

安裝完成之後,咱們能夠在個人電腦管理服務裏面看到才安裝上的後臺服務.測試

 

經測試,採用定時訪問數據庫發送短信的服務並非很耗資源,剛啓動的時候只佔用內存爲七、8M左右,通過在服務器上連續運行幾天不關閉佔用的內存也只升到15M左右,運行比較穩定,這裏提供一個短信二次開發接口說明,有興趣的朋友能夠去下載看下.

智網動力集團短信二次開發說明文檔示例

特別申明:本文及內容如非特別註明,均爲本人Jonllen原創,版權均歸原做者我的全部,轉載必須保留此段聲明源碼天空,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。

C#實現Windows後臺服務實例的基本狀況就向你介紹到這裏,但願對你瞭解和學習C#實現Windows後臺服務實例有所幫助。

詳細請參考:http://www.codesky.net/article/200908/128303.html

相關文章
相關標籤/搜索