轉(zhuǎn)帖|行業(yè)資訊|編輯:龔雪|2022-02-11 10:34:23.830|閱讀 241 次
概述:本文主要介紹如何在采集程序中增加定時發(fā)送郵件以及關(guān)機處理的實現(xiàn),歡迎下載文中實用控件體驗!
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
我們在采集特定數(shù)據(jù)的時候,往往需要耗費較長的時間,有時候因為一些事情,不可能長久的在電腦前等待結(jié)果,那么需要程序在一段時間后自動給我們發(fā)送郵件等通知,以及執(zhí)行退出程序或者關(guān)機等處理善后工作,以節(jié)省資源或者電源,那么需要實現(xiàn)這個過程是如何的呢。本篇隨筆基于這個采集程序的基礎(chǔ)上增加這些功能的實現(xiàn),介紹其中的一些處理技巧。
如果我們需要實現(xiàn)發(fā)送郵件、或者發(fā)送短信等通知途徑,那么我們就需要把這些處理過程涉及到的參數(shù)提前錄入到系統(tǒng)里面,是在不行硬編碼也行,不過為了可擴展性,我傾向于使用配置界面進行參數(shù)的配置。
在關(guān)于參數(shù)配置的處理,在博客《》以及《》都做了比較詳細(xì)的介紹,基于SettingsProvider.net的封裝處理,能夠?qū)崿F(xiàn)我們很方便的配置功能,可以配置在XML文件中,也可以保存在數(shù)據(jù)庫中,根據(jù)需要處理。
那么我這里為了采集發(fā)送數(shù)據(jù)的需要,也需要配置一個郵件的信息,如下界面所示。
這個里面放置額外的兩個功能按鈕,一個是郵箱設(shè)置參考,一個是發(fā)送測試郵件,前者用來輔助填入一些參數(shù),后者是驗證用戶賬號是否收到測試郵件。
發(fā)送測試郵件成功后,我們驗證下是否收到,以便核對下提供的參數(shù)是否正確。
完成上面的步驟后,我們基本上完成了一半的工作量了,剩下的就是在合適的時間,讓系統(tǒng)發(fā)送通知給我們以及善后處理即可。
那么我們?nèi)绻〞r的話,需要指定一個時間范圍,使用DevExpress的TimeSpanEdit控件就合適不過了,我們只需要確定小時:分鐘:秒的數(shù)據(jù)后,就可以根據(jù)這個時間范圍確定我們執(zhí)行任務(wù)的最終時間了。
這個彈出的小窗體,我們只用來獲取用戶輸入的時間范圍即可,沒有什么具體的邏輯。
輸入關(guān)機時間后,那么我們就可以根據(jù)關(guān)機時間,彈出一個倒計時的窗體,覆蓋在主程序的界面上。
最終我們到達時間的觸發(fā)點后,實現(xiàn)發(fā)送郵件通知以及退出程序或者關(guān)機的處理。
以上是整個處理的過程,那么實現(xiàn)的處理代碼是如何的呢,我們來分析下具體的代碼過程。
private bool isShutdown = false; private TimerHelper timerHelper; private void btnSendAndShutdown_Click(object sender, EventArgs e) { btnSendAndShutdown.Enabled = false; try { if (!isShutdown) { //獲取關(guān)機的時間 FrmShutdownTime frmTime = new FrmShutdownTime(); if (frmTime.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; //轉(zhuǎn)換為最終的時間 TimeSpan timeSpan = frmTime.timeShutdown.TimeSpan; this.endTime = DateTime.Now.Add(timeSpan); //定時器輔助類處理定時工作 timerHelper = new TimerHelper(1000, true); timerHelper.Execute += () => { //每隔一秒對事件進行處理判斷 if (ShutdownEvent != null) { ShutdownEvent(sender, e); } }; //顯示關(guān)機面板 groupShutdown.BringToFront(); groupShutdown.Visible = true; } else { //關(guān)閉面板 CloseShutDownGroup(); } isShutdown = !isShutdown; this.btnSendAndShutdown.Text = isShutdown ? "取消關(guān)機處理" : "定時發(fā)送郵件后關(guān)機"; } finally { btnSendAndShutdown.Enabled = true; } }
上面主要的處理邏輯,放在了定時器的處理事件上
ShutdownEvent(sender, e);
這個觸發(fā)的事件,是我們在主窗體定義的一個事件,目的就是用來實現(xiàn)倒計時及發(fā)送通知用的。
private event EventHandler ShutdownEvent;
然后我們在窗體里面初始化這個事件處理即可,初始化代碼如下所示。
//關(guān)閉或者退出程序的事件 this.ShutdownEvent += (s, e)=> { #region 定時處理操作 this.Invoke(new MethodInvoker(delegate() { //判斷當(dāng)前的剩余時間是否進入通知流程 var ts = endTime.Subtract(DateTime.Now); if (ts.TotalSeconds > 1) { //更新倒計時 timeLeft.TimeSpan = new TimeSpan(ts.Days, ts.Hours, ts.Minutes, ts.Seconds); } else { //關(guān)閉面板并退出定時器 CloseShutDownGroup(); //執(zhí)行發(fā)送郵件操作 SendMail(); //關(guān)閉主機或者退出程序 if (chkShutdown.Checked) { Process.Start("shutdown.exe", "-s");//關(guān)機 } else if (chkExitApp.Checked) { Application.ExitThread(); } } })); #endregion
最終的邏輯就是發(fā)送郵件和退出程序或者關(guān)機的處理:
//執(zhí)行發(fā)送郵件操作 SendMail(); //關(guān)閉主機或者退出程序 if (chkShutdown.Checked) { Process.Start("shutdown.exe", "-s");//關(guān)機 } else if (chkExitApp.Checked) { Application.ExitThread(); }
關(guān)機的操作,我們用來執(zhí)行命令行的方式實現(xiàn)關(guān)機的處理,非常方便。
關(guān)于這個Shutdown命令的處理,我下面列出它的一些功能說明。
shutdown命令的參數(shù):
shutdown.exe -s:關(guān)機
shutdown.exe -r:關(guān)機并重啟
shutdown.exe -l:注銷當(dāng)前用戶
shutdown.exe -s -t 時間:設(shè)置關(guān)機倒計時
shutdown.exe -h:休眠
shutdown.exe -t 時間:設(shè)置關(guān)機倒計時。默認(rèn)值是 30 秒。
shutdown.exe -a:取消關(guān)機
shutdown.exe -f:強行關(guān)閉應(yīng)用程序而沒有警告
shutdown.exe -m \計算機名:控制遠(yuǎn)程計算機
shutdown.exe -i:顯示“遠(yuǎn)程關(guān)機”圖形用戶界面,但必須是Shutdown的第一個參數(shù)
shutdown.exe -c "消息內(nèi)容":輸入關(guān)機對話框中的消息內(nèi)容
shutdown.exe -d [u][p]:xx:yy :列出系統(tǒng)關(guān)閉的原因代碼:u 是用戶代碼 ,p 是一個計劃的關(guān)閉代碼 ,xx 是一個主要原因代碼(小于 256 的正整數(shù)) ,yy 是一個次要原因代碼(小于 65536 的正整數(shù))
比如你的電腦要在12:00關(guān)機,可以選擇“開始→運行”,輸入“at 12:00 Shutdown -s",這樣,到了12點電腦就會出現(xiàn)“系統(tǒng)關(guān)機”對話框,默認(rèn)有30秒鐘的倒計時并提示你保存工作。
如果你想以倒計時的方式關(guān)機,可以輸入 “Shutdown.exe -s -t 3600",這里表示60分鐘后自動關(guān)機,“3600"代表60分鐘。
而發(fā)送郵件,我們一般利用一個郵件發(fā)送的封裝類處理下即可。
/// <summary> /// 發(fā)送郵件 /// </summary> private bool SendMail() { //統(tǒng)計數(shù)據(jù) btnSumaryData_Click(null, null); string title = string.Format("{0}期統(tǒng)計結(jié)果-{1}", Portal.gc.CurrentQSNumber, DateTime.Now); //獲取控件展示的內(nèi)容,并把它的換行轉(zhuǎn)換下 List<string> list = new List<string>(); list.AddRange(txtShenxiao.Lines); list.AddRange(this.txtShenxiao2.Lines); string content = string.Join("<br>", list); //發(fā)送郵件 var success = SendMailHelper.SendMail(title, content); return success; }
發(fā)送郵件的時候,我們先獲取用戶的郵件配置信息,然后調(diào)用郵件發(fā)送輔助類實現(xiàn)內(nèi)容的發(fā)送處理,具體代碼如下所示。
public class SendMailHelper { /// <summary> /// 發(fā)送郵件結(jié)果 /// </summary> public static bool SendMail(string title, string content) { //獲取配置的郵件信息 string creator = "";// LoginUserInfo.Name; ISettingsStorage store = new DatabaseStorage(creator); SettingsProvider settings = new SettingsProvider(store); bool result = false; EmailParameter parameter = settings.GetSettings<EmailParameter>(); if (parameter != null) { //使用郵件輔助類,實現(xiàn)郵件內(nèi)容的發(fā)送 EmailHelper email = new EmailHelper(parameter.SmtpServer, parameter.LoginId, parameter.Password); email.Subject = title; email.Body = content; email.IsHtml = true; email.Charset = "gb2312"; email.From = parameter.Email; email.FromName = parameter.Email; email.AddRecipient(parameter.Email); result = email.SendEmail(); } return result; }
以上就是整個處理的過程,其中還涉及到了在線程間訪問控件的方式,如下代碼所示。
這個詳細(xì)的介紹可以參考我較早期的隨筆《》,這些細(xì)節(jié)都需要我們一步步測試并尋找最佳的方案實現(xiàn),希望這個隨筆的思路給你有一定的啟發(fā)。
當(dāng)然,如果系統(tǒng)做的比較大一些,系統(tǒng)化一些的話,還可以考慮利用EasyNetQ的這種方式實現(xiàn)信息的通知。
這種通知可以更好的擴展,詳細(xì)介紹可以參考下隨筆《》,不過一般小程序的就不用那么麻煩了,用一個定時器來處理下就可以了。
DevExpress Universal 10月正式發(fā)布今年第二個重大版本——v21.2,此版本正式官宣支持Visual Studio 2022 & .NET6,同時與微軟最新發(fā)布的Windows 11完美兼容,全面解決用戶各種使用場景問題。 與時俱進,從未止步!
本文轉(zhuǎn)載自:
DevExpress技術(shù)交流群5:742234706 歡迎一起進群討論
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: