<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在開發程式的過程中,難免少不了寫入錯誤紀錄檔這個關鍵功能。實現這個功能,可以選擇使用第三方紀錄檔外掛,也可以選擇使用資料庫,還可以自己寫個簡單的方法把錯誤資訊記錄到紀錄檔檔案。現在我們來講下最後一種方法:
在選擇最後一種方法實現的時候,若對檔案操作與執行緒同步不熟悉,問題就有可能出現了,因為同一個檔案並不允許多個執行緒同時寫入,否則會提示“檔案正在由另一程序使用,因此該程序無法存取此檔案”。這是檔案的並行寫入問題,就需要用到執行緒同步。而微軟也給執行緒同步提供了一些相關的類可以達到這樣的目的,本文使用到的 System.Threading.ReaderWriterLockSlim 便是其中之一。該類用於管理資源存取的鎖定狀態,可實現多執行緒讀取或進行獨佔式寫入存取。利用這個類,我們就可以避免在同一時間段內多執行緒同時寫入一個檔案而導致的並行寫入問題。讀寫鎖是以 ReaderWriterLockSlim 物件作為鎖管理資源的,不同的 ReaderWriterLockSlim 物件中鎖定同一個檔案也會被視為不同的鎖進行管理,這種差異可能會再次導致檔案的並行寫入問題,所以 ReaderWriterLockSlim 應儘量定義為唯讀的靜態物件。
ReaderWriterLockSlim 有幾個關鍵的方法,本文僅討論寫入鎖:
1.呼叫 EnterWriteLock 方法 進入寫入狀態,在呼叫執行緒進入鎖定狀態之前一直處於阻塞狀態,因此可能永遠都不返回。
2.呼叫 TryEnterWriteLock 方法 進入寫入狀態,可指定阻塞的間隔時間,如果呼叫執行緒在此間隔期間並未進入寫入模式,將返回false。
3.呼叫 ExitWriteLock 方法 退出寫入狀態,應使用 finally 塊執行 ExitWriteLock 方法,從而確保呼叫方退出寫入模式。
程式碼:
class Program { static int LogCount = 100; static int WritedCount = 0; static int FailedCount = 0; static void Main(string[] args) { //迭代執行寫入紀錄檔記錄,由於多個執行緒同時寫入同一個檔案將會導致錯誤 Parallel.For(0, LogCount, e => { WriteLog1(); }); Console.WriteLine(string.Format("rnLog Count:{0}.ttWrited Count:{1}.tFailed Count:{2}.", LogCount.ToString(), WritedCount.ToString(), FailedCount.ToString())); Console.Read(); } #region 未加入讀寫鎖 //不使用讀寫鎖寫入檔案 static void WriteLog1() { try { var logFilePath = "log.txt"; var now = DateTime.Now; var logContent = string.Format("Tid: {0}{1} {2}.{3}rn", 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); } } #endregion }
執行結果:
不是所有的log都能寫入到log.txt,因為不適用讀寫錯可能會出現上面提到的:“檔案正在由另一程序使用,因此該程序無法存取此檔案”報錯資訊。
記錄log資訊:
Tid: 9 2021年5月21日 下午 02:18:04.919 Tid: 9 2021年5月21日 下午 02:18:04.944 Tid: 9 2021年5月21日 下午 02:18:05.80 Tid: 11 2021年5月21日 下午 02:18:05.81 Tid: 9 2021年5月21日 下午 02:18:05.82 Tid: 12 2021年5月21日 下午 02:18:05.83 Tid: 11 2021年5月21日 下午 02:18:05.84 Tid: 12 2021年5月21日 下午 02:18:05.84 Tid: 16 2021年5月21日 下午 02:18:05.85 Tid: 12 2021年5月21日 下午 02:18:05.111 Tid: 16 2021年5月21日 下午 02:18:05.117 Tid: 16 2021年5月21日 下午 02:18:05.128 Tid: 11 2021年5月21日 下午 02:18:05.128 Tid: 16 2021年5月21日 下午 02:18:05.133 Tid: 12 2021年5月21日 下午 02:18:05.138 Tid: 16 2021年5月21日 下午 02:18:05.140 Tid: 12 2021年5月21日 下午 02:18:05.140 Tid: 16 2021年5月21日 下午 02:18:05.142 Tid: 16 2021年5月21日 下午 02:18:05.144 Tid: 16 2021年5月21日 下午 02:18:05.151 Tid: 16 2021年5月21日 下午 02:18:05.158 Tid: 9 2021年5月21日 下午 02:18:05.159 Tid: 10 2021年5月21日 下午 02:18:05.159 Tid: 9 2021年5月21日 下午 02:18:05.164 Tid: 16 2021年5月21日 下午 02:18:05.164 Tid: 9 2021年5月21日 下午 02:18:05.172 Tid: 15 2021年5月21日 下午 02:18:05.172 Tid: 16 2021年5月21日 下午 02:18:05.181 Tid: 16 2021年5月21日 下午 02:18:05.187 Tid: 15 2021年5月21日 下午 02:18:05.188 Tid: 16 2021年5月21日 下午 02:18:05.195 Tid: 16 2021年5月21日 下午 02:18:05.196 Tid: 15 2021年5月21日 下午 02:18:05.195 Tid: 16 2021年5月21日 下午 02:18:05.202 Tid: 16 2021年5月21日 下午 02:18:05.203 Tid: 15 2021年5月21日 下午 02:18:05.202 Tid: 15 2021年5月21日 下午 02:18:05.207 Tid: 15 2021年5月21日 下午 02:18:05.209 Tid: 16 2021年5月21日 下午 02:18:05.207 Tid: 15 2021年5月21日 下午 02:18:05.210 Tid: 15 2021年5月21日 下午 02:18:05.222 Tid: 15 2021年5月21日 下午 02:18:05.231 Tid: 18 2021年5月21日 下午 02:18:05.238 Tid: 15 2021年5月21日 下午 02:18:05.238 Tid: 18 2021年5月21日 下午 02:18:05.244 Tid: 15 2021年5月21日 下午 02:18:05.251 Tid: 15 2021年5月21日 下午 02:18:05.256 Tid: 15 2021年5月21日 下午 02:18:05.262 Tid: 15 2021年5月21日 下午 02:18:05.304 Tid: 15 2021年5月21日 下午 02:18:05.312 Tid: 13 2021年5月21日 下午 02:18:05.312 Tid: 9 2021年5月21日 下午 02:18:05.313 Tid: 13 2021年5月21日 下午 02:18:05.320 Tid: 19 2021年5月21日 下午 02:18:05.320 Tid: 16 2021年5月21日 下午 02:18:05.325 Tid: 19 2021年5月21日 下午 02:18:05.333 Tid: 16 2021年5月21日 下午 02:18:05.342 Tid: 16 2021年5月21日 下午 02:18:05.349 Tid: 16 2021年5月21日 下午 02:18:05.361 Tid: 16 2021年5月21日 下午 02:18:05.366 Tid: 16 2021年5月21日 下午 02:18:05.367 Tid: 16 2021年5月21日 下午 02:18:05.368 Tid: 16 2021年5月21日 下午 02:18:05.376 Tid: 16 2021年5月21日 下午 02:18:05.386 Tid: 16 2021年5月21日 下午 02:18:05.392 Tid: 16 2021年5月21日 下午 02:18:05.401 Tid: 9 2021年5月21日 下午 02:18:05.463 Tid: 13 2021年5月21日 下午 02:18:05.464 Tid: 15 2021年5月21日 下午 02:18:05.464 Tid: 13 2021年5月21日 下午 02:18:05.465 Tid: 13 2021年5月21日 下午 02:18:05.470 Tid: 11 2021年5月21日 下午 02:18:05.479
程式碼:
class Program { static int LogCount = 100; static int WritedCount = 0; static int FailedCount = 0; static void Main(string[] args) { //迭代執行寫入紀錄檔記錄,由於多個執行緒同時寫入同一個檔案將會導致錯誤 Parallel.For(0, LogCount, e => { WriteLog2(); }); Console.WriteLine(string.Format("rnLog Count:{0}.ttWrited Count:{1}.tFailed Count:{2}.", LogCount.ToString(), WritedCount.ToString(), FailedCount.ToString())); Console.Read(); } #region 加入讀寫鎖 //讀寫鎖,當資源處於寫入模式時,其他執行緒寫入需要等待本次寫入結束之後才能繼續寫入 static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim(); static void WriteLog2() { try { //設定讀寫鎖為寫入模式獨佔資源,其他寫入請求需要等待本次寫入結束之後才能繼續寫入 //注意:長時間持有讀執行緒鎖或寫執行緒鎖會使其他執行緒發生飢餓 (starve)。 為了得到最好的效能,需要考慮重新構造應用程式以將寫存取的持續時間減少到最小。 //從效能方面考慮,請求進入寫入模式應該緊跟檔案操作之前,在此處進入寫入模式僅是為了降低程式碼複雜度 //因進入與退出寫入模式應在同一個try finally語句塊內,所以在請求進入寫入模式之前不能觸發異常,否則釋放次數大於請求次數將會觸發異常 LogWriteLock.EnterWriteLock(); var logFilePath = "log.txt"; var now = DateTime.Now; var logContent = string.Format("Tid: {0}{1} {2}.{3}rn", Thread.CurrentThread.ManagedThreadId.ToString().PadRight(4), now.ToLongDateString(), now.ToLongTimeString(), now.Millisecond.ToString()); File.AppendAllText(logFilePath, logContent); WritedCount++; } catch (Exception) { FailedCount++; } finally { //退出寫入模式,釋放資源佔用 //注意:一次請求對應一次釋放 //若釋放次數大於請求次數將會觸發異常[寫入鎖定未經保持即被釋放] //若請求處理完成後未釋放將會觸發異常[此模式不下允許以遞迴方式獲取寫入鎖定] LogWriteLock.ExitWriteLock(); } } #endregion }
執行結果:
所有的log都完全正確寫入到log.txt。
記錄log資訊:
Tid: 8 2021年5月21日 下午 02:26:36.573 Tid: 8 2021年5月21日 下午 02:26:36.597 Tid: 8 2021年5月21日 下午 02:26:36.599 Tid: 8 2021年5月21日 下午 02:26:36.600 Tid: 8 2021年5月21日 下午 02:26:36.601 Tid: 8 2021年5月21日 下午 02:26:36.602 Tid: 8 2021年5月21日 下午 02:26:36.608 Tid: 8 2021年5月21日 下午 02:26:36.609 Tid: 8 2021年5月21日 下午 02:26:36.614 Tid: 8 2021年5月21日 下午 02:26:36.616 Tid: 8 2021年5月21日 下午 02:26:36.617 Tid: 8 2021年5月21日 下午 02:26:36.620 Tid: 8 2021年5月21日 下午 02:26:36.620 Tid: 8 2021年5月21日 下午 02:26:36.621 Tid: 8 2021年5月21日 下午 02:26:36.622 Tid: 8 2021年5月21日 下午 02:26:36.623 Tid: 8 2021年5月21日 下午 02:26:36.624 Tid: 8 2021年5月21日 下午 02:26:36.624 Tid: 8 2021年5月21日 下午 02:26:36.625 Tid: 8 2021年5月21日 下午 02:26:36.626 Tid: 8 2021年5月21日 下午 02:26:36.626 Tid: 8 2021年5月21日 下午 02:26:36.627 Tid: 8 2021年5月21日 下午 02:26:36.628 Tid: 8 2021年5月21日 下午 02:26:36.628 Tid: 8 2021年5月21日 下午 02:26:36.629 Tid: 8 2021年5月21日 下午 02:26:36.630 Tid: 8 2021年5月21日 下午 02:26:36.630 Tid: 8 2021年5月21日 下午 02:26:36.631 Tid: 8 2021年5月21日 下午 02:26:36.632 Tid: 8 2021年5月21日 下午 02:26:36.632 Tid: 8 2021年5月21日 下午 02:26:36.633 Tid: 8 2021年5月21日 下午 02:26:36.634 Tid: 8 2021年5月21日 下午 02:26:36.634 Tid: 8 2021年5月21日 下午 02:26:36.635 Tid: 8 2021年5月21日 下午 02:26:36.636 Tid: 8 2021年5月21日 下午 02:26:36.636 Tid: 8 2021年5月21日 下午 02:26:36.637 Tid: 8 2021年5月21日 下午 02:26:36.638 Tid: 8 2021年5月21日 下午 02:26:36.638 Tid: 8 2021年5月21日 下午 02:26:36.639 Tid: 8 2021年5月21日 下午 02:26:36.641 Tid: 8 2021年5月21日 下午 02:26:36.641 Tid: 8 2021年5月21日 下午 02:26:36.642 Tid: 8 2021年5月21日 下午 02:26:36.643 Tid: 8 2021年5月21日 下午 02:26:36.644 Tid: 8 2021年5月21日 下午 02:26:36.644 Tid: 8 2021年5月21日 下午 02:26:36.645 Tid: 8 2021年5月21日 下午 02:26:36.646 Tid: 8 2021年5月21日 下午 02:26:36.647 Tid: 8 2021年5月21日 下午 02:26:36.647 Tid: 8 2021年5月21日 下午 02:26:36.648 Tid: 8 2021年5月21日 下午 02:26:36.649 Tid: 8 2021年5月21日 下午 02:26:36.650 Tid: 8 2021年5月21日 下午 02:26:36.650 Tid: 8 2021年5月21日 下午 02:26:36.651 Tid: 8 2021年5月21日 下午 02:26:36.652 Tid: 8 2021年5月21日 下午 02:26:36.652 Tid: 8 2021年5月21日 下午 02:26:36.652 Tid: 8 2021年5月21日 下午 02:26:36.653 Tid: 8 2021年5月21日 下午 02:26:36.654 Tid: 8 2021年5月21日 下午 02:26:36.655 Tid: 8 2021年5月21日 下午 02:26:36.656 Tid: 8 2021年5月21日 下午 02:26:36.658 Tid: 8 2021年5月21日 下午 02:26:36.658 Tid: 8 2021年5月21日 下午 02:26:36.659 Tid: 8 2021年5月21日 下午 02:26:36.660 Tid: 8 2021年5月21日 下午 02:26:36.660 Tid: 8 2021年5月21日 下午 02:26:36.661 Tid: 8 2021年5月21日 下午 02:26:36.662 Tid: 8 2021年5月21日 下午 02:26:36.662 Tid: 8 2021年5月21日 下午 02:26:36.663 Tid: 8 2021年5月21日 下午 02:26:36.664 Tid: 8 2021年5月21日 下午 02:26:36.664 Tid: 8 2021年5月21日 下午 02:26:36.665 Tid: 8 2021年5月21日 下午 02:26:36.666 Tid: 8 2021年5月21日 下午 02:26:36.666 Tid: 8 2021年5月21日 下午 02:26:36.667 Tid: 8 2021年5月21日 下午 02:26:36.668 Tid: 8 2021年5月21日 下午 02:26:36.669 Tid: 8 2021年5月21日 下午 02:26:36.669 Tid: 8 2021年5月21日 下午 02:26:36.670 Tid: 8 2021年5月21日 下午 02:26:36.671 Tid: 8 2021年5月21日 下午 02:26:36.672 Tid: 8 2021年5月21日 下午 02:26:36.673 Tid: 8 2021年5月21日 下午 02:26:36.675 Tid: 8 2021年5月21日 下午 02:26:36.675 Tid: 8 2021年5月21日 下午 02:26:36.676 Tid: 8 2021年5月21日 下午 02:26:36.677 Tid: 14 2021年5月21日 下午 02:26:36.678 Tid: 15 2021年5月21日 下午 02:26:36.679 Tid: 16 2021年5月21日 下午 02:26:36.680 Tid: 17 2021年5月21日 下午 02:26:36.681 Tid: 18 2021年5月21日 下午 02:26:36.681 Tid: 20 2021年5月21日 下午 02:26:36.683 Tid: 9 2021年5月21日 下午 02:26:36.683 Tid: 19 2021年5月21日 下午 02:26:36.684 Tid: 10 2021年5月21日 下午 02:26:36.685 Tid: 11 2021年5月21日 下午 02:26:36.685 Tid: 12 2021年5月21日 下午 02:26:36.687 Tid: 13 2021年5月21日 下午 02:26:36.688
到此這篇關於C#使用讀寫鎖解決多執行緒並行問題的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45