操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    1. 知識儲備

    在開發(fā)程序的過程中,難免少不了寫入錯誤日志這個關(guān)鍵功能。實現(xiàn)這個功能另一個程序正在使用此文件 進(jìn)程無法訪問,可以選擇使用第三方日志插件,也可以選擇使用數(shù)據(jù)庫,還可以自己寫個簡單的方法把錯誤信息記錄到日志文件。

    選擇最后一種方法實現(xiàn)的時候,若對文件操作與線程同步不熟悉,問題就有可能出現(xiàn)了另一個程序正在使用此文件 進(jìn)程無法訪問,因為同一個文件并不允許多個線程同時寫入,否則會提示“文件正在由另一進(jìn)程使用,因此該進(jìn)程無法訪問此文件”。

    這是文件的并發(fā)寫入問題,就需要用到線程同步。而微軟也給線程同步提供了一些相關(guān)的類可以達(dá)到這樣的目的,本文使用到的 .. 便是其中之一。

    vb使用hookdll禁止程序創(chuàng)建進(jìn)程_另一個程序正在使用此文件 進(jìn)程無法訪問_禁止程序訪問文件

    該類用于管理資源訪問的鎖定狀態(tài),可實現(xiàn)多線程讀取或進(jìn)行獨(dú)占式寫入訪問。利用這個類,我們就可以避免在同一時間段內(nèi)多線程同時寫入一個文件而導(dǎo)致的并發(fā)寫入問題。

    讀寫鎖是以 對象作為鎖管理資源的,不同的 對象中鎖定同一個文件也會被視為不同的鎖進(jìn)行管理,這種差異可能會再次導(dǎo)致文件的并發(fā)寫入問題,所以 應(yīng)盡量定義為只讀的靜態(tài)對象。

    有幾個關(guān)鍵的方法,本文僅討論寫入鎖:

    vb使用hookdll禁止程序創(chuàng)建進(jìn)程_另一個程序正在使用此文件 進(jìn)程無法訪問_禁止程序訪問文件

    2. 多線程同時寫入文件

    class?Program
    {
    ????static?int?LogCount?=?100;
    ????static?int?WritedCount?=?0;
    ????static?int?FailedCount?=?0;

    ????static?void?Main(string[]?args)
    ????{
    ????????//迭代運(yùn)行寫入日志記錄,由于多個線程同時寫入同一個文件將會導(dǎo)致錯誤
    ????????Parallel.For(0,?LogCount,?e?=>
    ????????{
    ????????????WriteLog();
    ????????});

    ????????Console.WriteLine(string.Format("\r\nLog?Count:{0}.\t\tWrited?Count:{1}.\tFailed?Count:{2}.",?LogCount.ToString(),?WritedCount.ToString(),?FailedCount.ToString()));
    ????????Console.Read();
    ????}

    ????static?void?WriteLog()
    ????{
    ????????try
    ????????{
    ????????????var?logFilePath?=?"log.txt";
    ????????????var?now?=?DateTime.Now;
    ????????????var?logContent?=?string.Format("Tid:?{0}{1}?{2}.{3}\r\n",?Thread.CurrentThread.ManagedThreadId.ToString().PadRight(4),?now.ToLongDateString(),?now.ToLongTimeString(),?now.Millisecond.ToString());
    ????????????File.AppendAllText(logFilePath,?logContent);
    ????????????WritedCount++;
    ????????}
    ????????catch?(Exception?ex)
    ????????{
    ????????????FailedCount++;
    ????????????Console.WriteLine(ex.Message);
    ????????}
    ????}
    }

    禁止程序訪問文件_另一個程序正在使用此文件 進(jìn)程無法訪問_vb使用hookdll禁止程序創(chuàng)建進(jìn)程

    3. 多線程使用讀寫鎖同步寫入文件

    class?Program
    {
    ????static?int?LogCount?=?100;
    ????static?int?WritedCount?=?0;
    ????static?int?FailedCount?=?0;

    ????static?void?Main(string[]?args)
    ????{
    ????????//迭代運(yùn)行寫入日志記錄
    ????????Parallel.For(0,?LogCount,?e?=>
    ????????{
    ????????????WriteLog();
    ????????});

    ????????Console.WriteLine(string.Format("\r\nLog?Count:{0}.\t\tWrited?Count:{1}.\tFailed?Count:{2}.",?LogCount.ToString(),?WritedCount.ToString(),?FailedCount.ToString()));
    ????????Console.Read();
    ????}

    ????//讀寫鎖,當(dāng)資源處于寫入模式時,其他線程寫入需要等待本次寫入結(jié)束之后才能繼續(xù)寫入
    ????static?ReaderWriterLockSlim?LogWriteLock?=?new?ReaderWriterLockSlim();
    ????static?void?WriteLog()
    ????{
    ????????try
    ????????{
    ????????????//設(shè)置讀寫鎖為寫入模式獨(dú)占資源,其他寫入請求需要等待本次寫入結(jié)束之后才能繼續(xù)寫入
    ????????????//注意:長時間持有讀線程鎖或?qū)懢€程鎖會使其他線程發(fā)生饑餓?(starve)。?為了得到最好的性能,需要考慮重新構(gòu)造應(yīng)用程序以將寫訪問的持續(xù)時間減少到最小。
    ????????????//??????從性能方面考慮,請求進(jìn)入寫入模式應(yīng)該緊跟文件操作之前,在此處進(jìn)入寫入模式僅是為了降低代碼復(fù)雜度
    ????????????//??????因進(jìn)入與退出寫入模式應(yīng)在同一個try?finally語句塊內(nèi),所以在請求進(jìn)入寫入模式之前不能觸發(fā)異常,否則釋放次數(shù)大于請求次數(shù)將會觸發(fā)異常
    ????????????LogWriteLock.EnterWriteLock();

    ????????????var?logFilePath?=?"log.txt";
    ????????????var?now?=?DateTime.Now;
    ????????????var?logContent?=?string.Format("Tid:?{0}{1}?{2}.{3}\r\n",?Thread.CurrentThread.ManagedThreadId.ToString().PadRight(4),?now.ToLongDateString(),?now.ToLongTimeString(),?now.Millisecond.ToString());

    ????????????File.AppendAllText(logFilePath,?logContent);
    ????????????WritedCount++;
    ????????}
    ????????catch?(Exception)
    ????????{
    ????????????FailedCount++;
    ????????}
    ????????finally
    ????????{
    ????????????//退出寫入模式,釋放資源占用
    ????????????//注意:一次請求對應(yīng)一次釋放
    ????????????//??????若釋放次數(shù)大于請求次數(shù)將會觸發(fā)異常[寫入鎖定未經(jīng)保持即被釋放]
    ????????????//??????若請求處理完成后未釋放將會觸發(fā)異常[此模式下允許以遞歸方式獲取寫入鎖定]
    ????????????LogWriteLock.ExitWriteLock();
    ????????}
    ????}
    }

    禁止程序訪問文件_另一個程序正在使用此文件 進(jìn)程無法訪問_vb使用hookdll禁止程序創(chuàng)建進(jìn)程

    使用讀寫鎖,全部日志成功寫入了日志文件。

    4. 測試復(fù)雜多線程環(huán)境下使用讀寫鎖同步寫入文件

    class?Program
    {
    ????static?int?LogCount?=?1000;
    ????static?int?SumLogCount?=?0;
    ????static?int?WritedCount?=?0;
    ????static?int?FailedCount?=?0;

    ????static?void?Main(string[]?args)
    ????{
    ????????//往線程池里添加一個任務(wù),迭代寫入N個日志
    ????????SumLogCount?+=?LogCount;
    ????????ThreadPool.QueueUserWorkItem((obj)?=>
    ????????{
    ????????????Parallel.For(0,?LogCount,?e?=>
    ????????????{
    ????????????????WriteLog();
    ????????????});
    ????????});

    ????????//在新的線程里,添加N個寫入日志的任務(wù)到線程池
    ????????SumLogCount?+=?LogCount;
    ????????var?thread1?=?new?Thread(()?=>
    ????????{
    ????????????Parallel.For(0,?LogCount,?e?=>
    ????????????{
    ????????????????ThreadPool.QueueUserWorkItem((subObj)?=>
    ????????????????{
    ????????????????????WriteLog();
    ????????????????});
    ????????????});
    ????????});
    ????????thread1.IsBackground?=?false;
    ????????thread1.Start();

    ????????//添加N個寫入日志的任務(wù)到線程池
    ????????SumLogCount?+=?LogCount;
    ????????Parallel.For(0,?LogCount,?e?=>
    ????????{
    ????????????ThreadPool.QueueUserWorkItem((obj)?=>
    ????????????{
    ????????????????WriteLog();
    ????????????});
    ????????});

    ????????//在新的線程里,迭代寫入N個日志
    ????????SumLogCount?+=?LogCount;
    ????????var?thread2?=?new?Thread(()?=>
    ????????{
    ????????????Parallel.For(0,?LogCount,?e?=>
    ????????????{
    ????????????????WriteLog();
    ????????????});
    ????????});
    ????????thread2.IsBackground?=?false;
    ????????thread2.Start();

    ????????//在當(dāng)前線程里,迭代寫入N個日志
    ????????SumLogCount?+=?LogCount;
    ????????Parallel.For(0,?LogCount,?e?=>
    ????????{
    ????????????WriteLog();
    ????????});

    ????????Console.WriteLine("Main?Thread?Processed.\r\n");
    ????????while?(true)
    ????????{
    ????????????Console.WriteLine(string.Format("Sum?Log?Count:{0}.\t\tWrited?Count:{1}.\tFailed?Count:{2}.",?SumLogCount.ToString(),?WritedCount.ToString(),?FailedCount.ToString()));
    ????????????Console.ReadLine();
    ????????}
    ????}

    ????//讀寫鎖,當(dāng)資源處于寫入模式時,其他線程寫入需要等待本次寫入結(jié)束之后才能繼續(xù)寫入
    ????static?ReaderWriterLockSlim?LogWriteLock?=?new?ReaderWriterLockSlim();
    ????static?void?WriteLog()
    ????{
    ????????try
    ????????{
    ????????????//設(shè)置讀寫鎖為寫入模式獨(dú)占資源,其他寫入請求需要等待本次寫入結(jié)束之后才能繼續(xù)寫入
    ????????????//注意:長時間持有讀線程鎖或?qū)懢€程鎖會使其他線程發(fā)生饑餓?(starve)。?為了得到最好的性能,需要考慮重新構(gòu)造應(yīng)用程序以將寫訪問的持續(xù)時間減少到最小。
    ????????????//??????從性能方面考慮,請求進(jìn)入寫入模式應(yīng)該緊跟文件操作之前,在此處進(jìn)入寫入模式僅是為了降低代碼復(fù)雜度
    ????????????//??????因進(jìn)入與退出寫入模式應(yīng)在同一個try?finally語句塊內(nèi),所以在請求進(jìn)入寫入模式之前不能觸發(fā)異常,否則釋放次數(shù)大于請求次數(shù)將會觸發(fā)異常
    ????????????LogWriteLock.EnterWriteLock();

    ????????????var?logFilePath?=?"log.txt";
    ????????????var?now?=?DateTime.Now;
    ????????????var?logContent?=?string.Format("Tid:?{0}{1}?{2}.{3}\r\n",?Thread.CurrentThread.ManagedThreadId.ToString().PadRight(4),?now.ToLongDateString(),?now.ToLongTimeString(),?now.Millisecond.ToString());

    ????????????File.AppendAllText(logFilePath,?logContent);
    ????????????WritedCount++;
    ????????}
    ????????catch?(Exception)
    ????????{
    ????????????FailedCount++;
    ????????}
    ????????finally
    ????????{
    ????????????//退出寫入模式,釋放資源占用
    ????????????//注意:一次請求對應(yīng)一次釋放
    ????????????//??????若釋放次數(shù)大于請求次數(shù)將會觸發(fā)異常[寫入鎖定未經(jīng)保持即被釋放]
    ????????????//??????若請求處理完成后未釋放將會觸發(fā)異常[此模式不下允許以遞歸方式獲取寫入鎖定]
    ????????????LogWriteLock.ExitWriteLock();
    ????????}
    ????}
    }

    禁止程序訪問文件_vb使用hookdll禁止程序創(chuàng)建進(jìn)程_另一個程序正在使用此文件 進(jìn)程無法訪問

    復(fù)雜多線程環(huán)境下使用讀寫鎖,全部日志成功寫入了日志文件,由和可以看出是由不同的線程同步寫入。

    5. 后記

    雖然讀寫IO有共享模式,也可以實現(xiàn)但不推薦

    static?void?WriteLog()
    {
    ????try
    ????{
    ????????var?logFilePath?=?"log.txt";
    ????????var?now?=?DateTime.Now;
    ????????var?logContent?=?string.Format("Tid:?{0}{1}?{2}.{3}\r\n",?Thread.CurrentThread.ManagedThreadId.ToString().PadRight(4),?now.ToLongDateString(),?now.ToLongTimeString(),?now.Millisecond.ToString());
    ????????//File.AppendAllText(logFilePath,?logContent);
    ?
    ????????var?logContentBytes?=?Encoding.Default.GetBytes(logContent);
    ????????using?(FileStream?logFile?=?new?FileStream(logFilePath,?FileMode.OpenOrCreate,?FileAccess.Write,?FileShare.Write))
    ????????{
    ????????????logFile.Seek(0,?SeekOrigin.End);
    ????????????logFile.Write(logContentBytes,?0,?logContentBytes.Length);
    ????????}
    ?
    ????????WritedCount++;
    ????}
    ????catch?(Exception?ex)
    ????{
    ????????FailedCount++;
    ????????Console.WriteLine(ex.Message);
    ????}
    }

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有