国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

一步步開發(fā)自己的博客番外篇(7、異步記錄日志和文章閱讀量統(tǒng)計)

2019-11-14 15:46:10
字體:
供稿:網(wǎng)友

前言 

離前一篇《一步步開發(fā)自己的博客  .NET版(6、手機端的兼容)》都個把月了。

當(dāng)時寫完第六篇,很多人問“劇終”了?你還有好多實現(xiàn)沒有講解分析呢。我說沒呢,后期還會有第二版、第三版...至于還沒有分析到,后期補上。你看,我今天不就來了么。

前段時間寫代碼,手都寫的酸痛酸痛的,歇息了幾天,好多了。然后,又搗鼓了一下webapi。這也是個沒有接觸過的知識。跌跌撞撞的整了點東西出來。有興趣寫移動端的同學(xué)可以聯(lián)系我,大家一起學(xué)習(xí)。API文檔和測試地址:http://haojima.net/SwaggerUI 

其他的就不多說了,進入今天的主題,異步記錄日志和文章閱讀量統(tǒng)計。

     

異步記錄日志

我們常用日志記錄,無非就是,數(shù)據(jù)庫記錄和文本日志記錄。而今天我要說的是,文本日志記錄。

最簡單的文本記錄: File.WriteAllText(path,messg); 使用靜態(tài)類File的WriteAllText 如果文件存在則覆蓋,傳入文件路徑和消息內(nèi)容。ok,完事。

當(dāng)然,我們不能每次都覆蓋上一次的記錄。 File.AppendAllText(path,messg); 那么我們可是在原有內(nèi)容追加。這里,我們不用關(guān)系文件流是否關(guān)閉,使用靜態(tài)類File的這兩個方法都會自動幫我們關(guān)閉。

如果,我們是使用的winfrom單線程。那么,基本的日志記錄就這個兩個方法 完全可以搞定。

但是,如果是web程序就不一樣了,天生的多線程。多個線程同時訪問一個文件,肯定是會報錯的。不信你試試。

那我們怎么解決這個問題?有人會說,加鎖唄。鎖肯定是要加,不過要看怎么加了。如果加到寫文件內(nèi)容的時候肯定是不合適的。因為寫文件要打開文件流,比較耗時。我們可以先把要寫的日志,統(tǒng)一存內(nèi)存,然后單線程從內(nèi)存取數(shù)據(jù),寫到文本。當(dāng)然,寫內(nèi)存也可能會多線程并發(fā),這個時候,我們就可以把鎖加到寫內(nèi)存的地方。這里大家就不用擔(dān)心了,寫內(nèi)存的速度是非常快的,和直接寫文件那差的可不是一兩個檔次的問題了。

我們剛才說存內(nèi)存,怎么存?當(dāng)然是存集合了。有個數(shù)據(jù)類型 Queue 為什么要用它。因為它是隊列,有個特點:先進先出。我們?nèi)?shù)據(jù)的時候就是去的最早存進去的數(shù)據(jù)了。

使用:存數(shù)據(jù) Queue myQ = new Queue(); myQ.Enqueue("The");//入隊    取數(shù)據(jù) var t = myQ.Dequeue(); 直接在取值的時候就把值在隊列中移除了。這樣正好免了我手動移除。

那么,很簡單。我們記日志的時候就先把日志往 Queue 里存,然后單獨開個進程取值存值寫文件里。ok,完事。

剛才說了,我們要加鎖。是的,要加鎖。因為 Queue 并不是線程安全數(shù)據(jù)。我們在寫數(shù)據(jù)和讀數(shù)據(jù)的時候都要加鎖。

static object myLock= new object();...lock (myLock)     logQueue.Enqueue(logmede);//...lock (myLock)     var m = logQueue.Dequeue();//

 

我之前在網(wǎng)上查資料說不能多線程同時寫入隊列,經(jīng)測試其實是不能同時讀和寫隊列。所以在Dequeue取的時候也要鎖定同一個對象

思路大體就是這樣了。當(dāng)然,我們還可以擴展很多的東西。如:定時刪除指定過期日志、分文件大小存儲日志、自動增加的日志文件命名...等等。

寫到這里,估計又有大把大把的人要來批判我了。又在造輪子。日志框架那么多,干嘛還要自己寫。浪費時間.....等。

沒錯,我確實是在造輪子。我不想解釋太多了。累...   大神請略過....

下面給出,我的具體實現(xiàn)代碼。分為四個文件 LogMode 包含文件名、日志內(nèi)容 LogHelper 存隊列、寫文件 LogConfig 讀取相關(guān)配置 LogSave 外部直接調(diào)用

using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web;namespace CommonLib.HiLog{    /// <summary>    /// 日志模型    /// </summary>    internal class LogModel    {              #region logFileName        PRivate string _logFileName;        /// <summary>        /// 日志文件名字        /// </summary>        public string logFileName        {            get { return _logFileName + "_" + DateTime.Now.ToString("yyyyMMdd"); }            set { _logFileName = value; }        }        #endregion        #region logMessg        private string _logMessg;        /// <summary>        /// 日志內(nèi)容        /// </summary>        public string logMessg        {            get            {                return "----begin-------" + DateTime.Now.ToString() + "----Queue.Count:" + LogHelper.LogQueue.Count + "-----------------------------------/r/n/r/n"                    + _logMessg                    + "/r/n/r/n----end----------" + DateTime.Now.ToString() + "----Queue.Count:" + LogHelper.LogQueue.Count + "-----------------------------------"                    + "/r/n/r/n/r/n";            }            set { _logMessg = value; }        }        #endregion    }}
View Code
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace CommonLib.HiLog{    /// <summary>    /// 日志操作輔助類    /// zhaopeiym@163.com    /// 創(chuàng)建20150104 修改20151003    /// </summary>    internal class LogHelper    {        /// <summary>        /// 消息隊列        /// </summary>        private static Queue<LogModel> logQueue = new Queue<LogModel>();        /// <summary>        /// 消息隊列 對外只讀        /// </summary>        public static Queue<LogModel> LogQueue        {            get { return LogHelper.logQueue; }        }        /// <summary>        /// 標(biāo)志鎖        /// </summary>        static string myLock = "true";        /// <summary>        /// 寫入日志文件(異步單線程 記錄日志)        /// </summary>        /// <param name="logmede"></param>        public static void logWrite(LogModel logmede)        {            // 這里需要鎖上 不然會出現(xiàn):源數(shù)組長度不足。請檢查 srcIndex 和長度以及數(shù)組的下限。異常               //網(wǎng)上有資料說 http://blog.csdn.net/greatbody/article/details/26135057  不能多線程同時寫入隊列            //其實  不僅僅 不能同時寫入隊列 也不能同時讀和寫如隊列  所以  在Dequeue 取的時候也要鎖定一個對象            lock (myLock)                logQueue.Enqueue(logmede);            logStartWrite();        }        /// <summary>        /// 文件編碼格式        /// </summary>        public static Encoding encoding = Encoding.Default;        /// <summary>        /// 是否開始自動記錄日志        /// </summary>        private static bool isStart = false;        /// <summary>        /// 用來 標(biāo)識 最好一次 檢測是否 需要 清理 日志文件 時間        /// </summary>        private static DateTime time = DateTime.MinValue;        /// <summary>        /// 每個日志文件夾 對應(yīng)的文件下標(biāo)        /// </summary>        private static Dictionary<string, int> logFileNum = new Dictionary<string, int>();        /// <summary>        /// 開始把隊列消息寫入文件        /// </summary>        private static void logStartWrite()        {            if (isStart)                return;            isStart = true;            Task.Run(() =>            {                while (true)                {                    if (LogHelper.logQueue.Count >= 1)                    {                        LogModel m = null;                        lock (myLock)                            m = LogHelper.logQueue.Dequeue();                        if (m == null)                            continue;                        if (string.IsNullOrEmpty(LogConfig.logFilePath))                            throw new Exception("請先初始化日志保存路徑LogModel._logFilePath");                        TestingInvalid();                        if (!Directory.Exists(LogConfig.logFilePath + m.logFileName + @"/"))                            Directory.CreateDirectory(LogConfig.logFilePath + m.logFileName + @"/");                        // int i = m.logFileNum;                        if (!logFileNum.Keys.Contains(m.logFileName))                            logFileNum.Add(m.logFileName, 0);                        //部分 日志 文件路徑                        string SectionfileFullName = LogConfig.logFilePath + m.logFileName + @"/" + m.logFileName + "_" + logFileNum[m.logFileName].ToString("000") + ".txt";                        //最新的寫了內(nèi)容的 部分 日志文件路徑                        string TopSectionfileFullName = SectionfileFullName;                        // 需要實時更新的 最新日志文件 路徑                        string LogfileFullNqme = LogConfig.logFilePath + m.logFileName + @"/" + m.logFileName + ".txt";                        FileInfo file = new FileInfo(SectionfileFullName);                        while (file.Exists && file.Length >= LogConfig.SectionlogFileSize)                        {                            TopSectionfileFullName = SectionfileFullName;                            logFileNum[m.logFileName]++;                            SectionfileFullName = LogConfig.logFilePath + m.logFileName + @"/" + m.logFileName + "_" + logFileNum[m.logFileName].ToString("000") + ".txt";                            file = new FileInfo(SectionfileFullName);                        }                        try                        {                            if (!file.Exists)//如果不存在 這個文件 就說明需要 創(chuàng)建新的部分日志文件了                            {                                //因為SectionfileFullName路徑的文件不存在    所以創(chuàng)建                                File.WriteAllText(SectionfileFullName, m.logMessg, encoding);                                FileInfo Logfile = new FileInfo(LogfileFullNqme);                                if (Logfile.Exists && Logfile.Length >= LogConfig.FileSize)                                    //先清空  然后加上 上一個部分文件的內(nèi)容                                    File.WriteAllText(LogfileFullNqme, File.ReadAllText(TopSectionfileFullName, encoding), encoding);//如果存在則覆蓋                                                       }                            else                                File.AppendAllText(SectionfileFullName, m.logMessg, encoding);//累加                            //追加這次內(nèi)容 到動態(tài)更新的日志文件                            File.AppendAllText(LogfileFullNqme, m.logMessg, encoding);                        }                        catch (Exception ex)                        {                            throw ex;                        }                    }                    else                    {                        isStart = false;//標(biāo)記下次可執(zhí)行                        break;//跳出循環(huán)                    }                }            });        }        /// <summary>        /// 檢測 并刪除 之前之外的 日志文件        /// </summary>        public static void TestingInvalid()        {            #region 檢測 并刪除 之前之外的 日志文件            if (time.AddMinutes(LogConfig.TestingInterval) <= DateTime.Now)// 時間內(nèi) 檢測一次            {                try                {                    time = DateTime.Now;                    List<string> keyNames = new List<string>();                    foreach (var logFileName in logFileNum.Keys)                    {                        CreatePath(LogConfig.logFilePath + logFileName + @"/");                        DirectoryInfo dir = new DirectoryInfo(LogConfig.logFilePath + logFileName + @"/");                        if (dir.CreationTime.AddMinutes(LogConfig.DelInterval) <= DateTime.Now)//刪除 設(shè)定時間 之前的日志                            foreach (var fileInfo in dir.GetFiles())                            {                                if (fileInfo.LastWriteTime.AddMinutes(LogConfig.DelInterval) <= DateTime.Now)//最后修改時間算起                                    File.Delete(fileInfo.FullName);                            }                        if (dir.GetFiles().Length == 0)                            keyNames.Add(logFileName);//臨時存儲沒有日志文件的文件夾                    }                    foreach (var key in keyNames)//刪除沒有日志文件的文件夾                    {                        logFileNum.Remove(key);                        Directory.Delete(LogConfig.logFilePath + key + @"/", false);                    }                }                catch (Exception ex)                {                    LogSave.ErrLogSave("手動捕獲[檢測并刪除日志出錯!]", ex, "記錄日志出錯");                }                            }            #endregion        }        #region  創(chuàng)建路徑        /// <summary>        /// 創(chuàng)建路徑        /// </summary>        /// <param name="paht"></param>        /// <returns></returns>        public static bool CreatePath(string paht)        {            if (!Directory.Exists(paht))            {                Directory.CreateDirectory(paht);                return true;            }            return false;        }        #endregion    }}
View Code
using System;using System.Collections.Generic;using System.Configuration;using System.Data;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Web;namespace CommonLib.HiLog{    /// <summary>    /// 日志相關(guān)配置        /// </summary>    public static class LogConfig    {        #region 輔助方法        /// <summary>        /// GetAppSettings        /// </summary>        /// <param name="key"></param>        /// <returns></returns>        public static string GetAppSettings(string key)        {            if (ConfigurationManager.AppSettings.AllKeys.Contains(key))                return ConfigurationManager.AppSettings[key].ToString();            return string.Empty;        }        /// <summary>        /// 計算字符串 轉(zhuǎn) 計算結(jié)果        /// </summary>        /// <param name="v"></param>        /// <returns></returns>        public static string toCompute(this string v)        {            return new DataTable().Compute(v, "").ToString();        }        #endregion        #region 靜態(tài)屬性和字段        #region logFilePath 路徑        /// <summary>        /// 日志要存的路徑 默認路徑:網(wǎng)站根目錄 + Log 文件夾        /// 在程序第一次啟動是設(shè)置        /// </summary>               private static string _logFilePath;        /// <summary>        /// 日志要存的路徑 默認路徑:網(wǎng)站根目錄 + Log 文件夾        /// 在程序第一次啟動是設(shè)置        /// </summary>           public static string logFilePath        {            get            {                if (string.IsNullOrEmpty(_logFilePath))                {                    try                    {                        _logFilePath = HttpContext.Current.Server.MapPath("~/");                    }                    catch (Exception)                    {                        try                        {                            _logFilePath = System.Windows.Forms.application.StartupPath + @"/";                        }                        catch (Exception)                        {                            throw new Exception("請先初始化要保存的路徑:LogModel._logFilePath");                        }                    }                }                return _logFilePath;            }            set            {                _logFilePath = value;            }        }        #endregion        #region 檢測間隔時間(分鐘)        private static int _TestingInterval;        /// <summary>        /// 檢測間隔時間(分鐘) 默認:一天        /// 配置:appSettings->Log_TestingInterval 單位:秒        /// </summary>        public static int TestingInterval        {            get            {                if (_TestingInterval <= 0)                {                    var Log_TestingInterval = GetAppSettings("Log_TestingInterval");                    if (string.IsNullOrEmpty(Log_TestingInterval))                        _TestingInterval = 1 * 60 * 24;                    else                        _TestingInterval = Convert.ToInt32(Log_TestingInterval.toCompute());                }                return _TestingInterval;            }        }        #endregion        #region 刪除 N分鐘(最后修改時間)之前的的日志        private static int _DelInterval;        /// <summary>        /// 刪除 N分鐘(最后修改時間)之前的的日志 默認:15天        /// 配置:appSettings->Log_DelInterval 單位:秒        /// </summary>        public static int DelInterval        {            get            {                if (_DelInterval <= 0)                {                    var Log_DelInterval = GetAppSettings("Log_DelInterval");                    if (string.IsNullOrEmpty(Log_DelInterval))                        _DelInterval = 1 * 60 * 24 * 15;                    else                        _DelInterval = Convert.ToInt32(Log_DelInterval.toCompute());                }                return _DelInterval;            }        }        #endregion        #region 部分日志文件大小(Byte)        private static int _SectionlogFileSize;        /// <summary>        /// 部分日志文件大小(Byte) 默認:1024Byte * 1024 * 1 = 1MB        /// 配置:appSettings->Log_SectionlogFileSize 單位:Byte        /// </summary>        public static int SectionlogFileSize        {            get            {                if (_SectionlogFileSize <= 0)                {                    var Log_SectionlogFileSize = GetAppSettings("Log_SectionlogFileSize");                    if (string.IsNullOrEmpty(Log_SectionlogFileSize))                        _SectionlogFileSize = 1024 * 1024 * 1;                    else                        _SectionlogFileSize = Convert.ToInt32(Log_SectionlogFileSize.toCompute());                }                return _SectionlogFileSize;            }        }        #endregion        #region 變動文件大小(Byte)        private static int _FileSize;        /// <summary>        /// 變動文件大小(Byte) 默認:1024 * 1024 * 4 = 4M        /// 配置:appSettings->Log_FileSize 單位:Byte        /// </summary>        public static int FileSize        {            get            {                if (_FileSize <= 0)                {                    var Log_FileSize = GetAppSettings("Log_FileSize");                    if (string.IsNullOrEmpty(Log_FileSize))                        _FileSize = 1024 * 1024 * 4;                    else                        _FileSize = Convert.ToInt32(Log_FileSize.toCompute());                }                return _FileSize;            }        }        #endregion        #endregion    }}
View Code
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Web;namespace CommonLib.HiLog{    /// <summary>    /// 異步單線程    /// </summary>    public class LogSave    {        /// <summary>        /// 獲得Exception 的詳細信息        /// </summary>        /// <param name="ex"></param>        /// <returns></returns>        public static string GetExceptionInfo(Exception ex)        {            StringBuilder str = new StringBuilder();            str.Append("錯誤信息:" + ex.Message);            str.Append("/r/n錯誤源:" + ex.Source);            str.Append("/r/n異常方法:" + ex.TargetSite);            str.Append("/r/n堆棧信息:" + ex.StackTrace);            return str.ToString();        }        /// <summary>        /// 系統(tǒng) 自動 捕捉異常        /// 保存異常詳細信息         /// 包括: 瀏覽器  瀏覽器版本 操作系統(tǒng) 頁面  Exception        /// </summary>        /// <param name="ex"></param>        /// <param name="fileName">文件名 默認:SysErr</param>        public static void SysErrLogSave(Exception ex, string fileName = null)        {            StringBuilder str = new StringBuilder();            string ip = "";            if (HttpContext.Current.Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR") != null)                ip = HttpContext.Current.Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR").ToString().Trim();            else                ip = HttpContext.Current.Request.ServerVariables.Get("Remote_Addr").ToString().Trim();            str.Append("Ip:" + ip);            str.Append("/r/n瀏覽器:" + HttpContext.Current.Request.Browser.Browser.ToString());            str.Append("/r/n瀏覽器版本:" + HttpContext.Current.Request.Browser.MajorVersion.ToString());            str.Append("/r/n操作系統(tǒng):" + HttpContext.Current.Request.Browser.Platform.ToString());            str.Append("/r/n頁面:" + HttpContext.Current.Request.Url.ToString());            str.Append("/r/n" + GetExceptionInfo(ex));            LogHelper.logWrite(new LogModel()            {                logFileName = "SysErr" + fileName ?? string.Empty,                logMessg = str.ToString()            });        }        /// <summary>        /// 異常日志記錄        /// </summary>        /// <param name="strmes"></param>        /// <param name="ex"></param>        public static void ErrLogSave(string strmes, Exception ex, string fileName = null)        {            StringBuilder str = new StringBuilder();            str.Append(strmes);            if (ex != null)                str.Append("/r/n" + GetExceptionInfo(ex));            LogHelper.logWrite(new LogModel()            {                logFileName = fileName ?? "Err",                logMessg = str.ToString()            });        }        /// <summary>        /// 警告日志記錄        /// </summary>        /// <param name="str"></param>        public static void WarnLogSave(string str, string fileName = null)        {            if (str != null && !string.IsNullOrEmpty(str.Trim()))                LogHelper.logWrite(new LogModel()                {                    logFileName = fileName ?? "Warn",                    logMessg = str                });        }        /// <summary>        /// 追蹤日志記錄        /// </summary>        /// <param name="str"></param>        public static void TrackLogSave(string str, string fileName = null)        {            if (str != null && !string.IsNullOrEmpty(str.Trim()))                LogHelper.logWrite(new LogModel()                {                    logFileName = fileName ?? "Track",                    logMessg = str                });        }        /// <summary>        /// 追蹤日志記錄        /// </summary>        /// <param name="str"></param>        public static void TrackLogSave(string str)        {            if (!string.IsNullOrEmpty(str.Trim()))                LogHelper.logWrite(new LogModel()                {                    logFileName = "SqlTrack",                    logMessg = str                });        }    }}
View Code

寫好之后,下次我在別的項目里面就直接引用。

如果你使用的是EF,那么我再告訴你一個小秘密。 DbContext 中的 Database.Log 可以直接記錄所有EF執(zhí)行的sql語句和參數(shù)。

使用如: dbContext.Database.Log = LogSave.TrackLogSave;  而LogSave.TrackLogSave我們在上面已經(jīng)封裝過。

效果圖1  效果圖2 

文章閱讀量統(tǒng)計

我在一開始就琢磨著怎么統(tǒng)計閱讀量。之前也在http://www.survivalescaperooms.com/zhaopei/p/4744846.html的最后提出了這個疑問。

遺憾的是,并沒有誰告訴我更好的解決方案。

好吧,靠人不如靠己。還是自己瞎折騰吧。

但是,實現(xiàn)方式還是使用的我自己的提出的“如果實在是找不到好的解決方案,我打算用 IP+系統(tǒng)版本+瀏覽器版本號+.... 作為“聯(lián)合主鍵”,如果“主鍵”24小時內(nèi)重復(fù)兩次以上,則不統(tǒng)計,如果cookie存在也不統(tǒng)計。

1、我們在每次瀏覽器訪問的時候都種下cookie,并設(shè)置過期時間為24小時。下次,瀏覽器訪問的時候。我們檢測如果存在我們種下的cookie。則直接忽略。

2、如果沒有帶上我們的cookie。我們就先組合“聯(lián)合主鍵”。然后檢測24小時內(nèi)的記錄有沒有這個“聯(lián)合主鍵”。如果有,則忽略,否則在原有閱讀量的基礎(chǔ)上加一,然后存入“聯(lián)合主鍵”。

這里的"聯(lián)合主鍵"有個小技巧。大家肯定都發(fā)現(xiàn)了,這個主鍵有點長。存數(shù)據(jù)庫有點浪費空間(我數(shù)據(jù)庫本來就只有50M),然后查詢檢索應(yīng)該也會慢些吧(并不清楚)。我們想想,其實我們要的不是這么長一串東東。其實,我們只要得到這串東西代表的唯一性就可以了。那么我們可以用到md5,咱不管你是1G、2G還是高清或是無碼。統(tǒng)統(tǒng)給你返回一定長度字符串(我取的是16位小寫)。

隨著數(shù)據(jù)的增加,這個統(tǒng)計閱讀量的表數(shù)據(jù),肯定是所有表中最大的。然而,我們統(tǒng)計閱讀量是在,點擊訪問文章的時候,然后在統(tǒng)計閱讀量這個環(huán)節(jié)卡太久,給人的感覺就是這個頁面訪問太慢,體驗不好。

然而,我們每次統(tǒng)計都需要檢測數(shù)據(jù)庫里面是否存在,且數(shù)據(jù)量還不小。那我們只有再開個進程來做統(tǒng)計。

具體實現(xiàn)代碼:

#region 判斷是否閱讀過 如果沒有 這在BlogReadInfo 插入一條標(biāo)識信息private bool IsRead(Blogs.ModelDB.Blogs blogobj, string md5){    if (blogobj.BlogReadInfo.Where(t => t.MD5 == md5 && t.LastTime.AddHours(24) > DateTime.Now).Count() > 0)        return true;    else    {        //BLL.        blogobj.BlogReadInfo.Add(new Blogs.ModelDB.BlogReadInfo()        {            MD5 = md5,            IsDel = false,            BlogsId = blogobj.Id,            CreateTime = DateTime.Now,            UpTime = DateTime.Now,            LastTime = DateTime.Now        });        return false;    }}#endregion
#region 統(tǒng)計閱讀量 異步調(diào)用方法delegate void SaveReadDelegate(ModelDB.Blogs blogobj, string md5);private void SaveReadNum(ModelDB.Blogs blogobj, string md5){    LogSave.TrackLogSave(GetUserDistinguish(Request, false), "ReadBlogLog");    var isup = true;    BLL.BlogsBLL blogbll = new BLL.BlogsBLL();    var blogtemp = blogbll.GetList(t => t.Id == blogobj.Id, isAsNoTracking: false).FirstOrDefault();    if (blogtemp.BlogReadNum == null)        blogtemp.BlogReadNum = 1;    else if (!IsRead(blogtemp, md5))        blogtemp.BlogReadNum++;    else        isup = false;    if (isup)        BLL.BlogCommentSetBLL.StaticSave();}
#region 獲取客戶端標(biāo)識(偽)/// <summary>///  獲取客戶端標(biāo)識 用來判斷是否已經(jīng)閱讀過此文章/// </summary>/// <param name="requestt"></param>/// <param name="IsMD5">是否已經(jīng)md5加密</param>/// <returns></returns>private string GetUserDistinguish(HttpRequestBase requestt, bool IsMD5 = true){    //request    StringBuilder str = new StringBuilder();    string ip = "";    if (requestt.ServerVariables.AllKeys.Contains("HTTP_X_FORWARDED_FOR") && requestt.ServerVariables.Get("HTTP_X_FORWARDED_FOR") != null)        ip = requestt.ServerVariables.Get("HTTP_X_FORWARDED_FOR").ToString().Trim();    else        ip = requestt.ServerVariables.Get("Remote_Addr").ToString().Trim();    str.Append("Ip:" + ip);    str.Append("/r/n瀏覽器:" + requestt.Browser.Browser.ToString());    str.Append("/r/n瀏覽器版本:" + requestt.Browser.MajorVersion.ToString());    str.Append("/r/n操作系統(tǒng):" + requestt.Browser.Platform.ToString());    str.Append("/r/n頁面:" + requestt.Url.ToString());    //str.Append("客戶端IP:" + requestt.UserHostAddress);    str.Append("/r/n用戶信息:" + User);    str.Append("/r/n瀏覽器標(biāo)識:" + requestt.Browser.Id);    str.Append("/r/n瀏覽器版本號:" + requestt.Browser.Version);    str.Append("/r/n瀏覽器是不是測試版本:" + requestt.Browser.Beta);    //str.Append("<br/>瀏覽器的分辨率(像素):" + Request["width"].ToString() + "*" + Request["height"].ToString());//1280/1024                            str.Append("/r/n是不是win16系統(tǒng):" + requestt.Browser.Win16);    str.Append("/r/n是不是win32系統(tǒng):" + requestt.Browser.Win32);    if (IsMD5)        return str.ToString().GetMd5_16();    else        return str.ToString();}#endregion

(當(dāng)然,這個方式統(tǒng)計也不一定準。請求頭信息改改就被偽造了。)

然后我們通過委托從線程池抓去線程異步調(diào)用

//........................異步調(diào)用....................new SaveReadDelegate(SaveReadNum).BeginInvoke(blogobj, GetUserDistinguish(Request), null, null);

ok,統(tǒng)計完事。 

 

如果您對本篇文章感興趣,那就麻煩您點個贊,您的鼓勵將是我的動力。      

當(dāng)然您還可以加入QQ群:469075305討論。

如果您有更好的處理方式,希望不要吝嗇賜教。

一步步開發(fā)自己的博客 .NET版系列:http://www.survivalescaperooms.com/zhaopei/tag/Hi-Blogs/

本文鏈接:http://www.survivalescaperooms.com/zhaopei/p/4887573.html 

 

朋友找工作,資深.NET高級工程師。博文鏈接:http://www.survivalescaperooms.com/CreateMyself

“賣身契:本人正找工作中,工作地點:深圳,方向:.NET。欲知更多詳細內(nèi)容請與我聯(lián)系QQ(2752154844)或留下你的聯(lián)系方式,非誠勿擾。”


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 陈巴尔虎旗| 金沙县| 彭山县| 漯河市| 合阳县| 济阳县| 浦城县| 潞城市| 射洪县| 井陉县| 柳江县| 平阴县| 苍溪县| 会理县| 原阳县| 门源| 龙胜| 吉林省| 永安市| 南开区| 南部县| 嫩江县| 西吉县| 三穗县| 安平县| 穆棱市| 玉林市| 莫力| 青河县| 内江市| 四川省| 榆树市| 云和县| 镇江市| 迁西县| 龙门县| 株洲县| 公主岭市| 宿松县| 哈尔滨市| 武宁县|