亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

關于.net線程安全問題

關于.net線程安全問題

largeQ 2018-12-07 09:13:01
public class Logger??? {??????????????? private Queue queue;??????? private ManualResetEvent manual; ?????????????? private Thread logThread;??????? /// ??????? /// 指定存儲文件的路徑??????? /// ??????? public static string Path { get; set; } ??????? //私有構造函數,初始化相關對象 使用單例模式??????? private Logger()??????? {??????????? queue = new Queue();??????????? manual = new ManualResetEvent(false);??????????? logThread = new Thread(Process);??????????? logThread.IsBackground = true;??????????? logThread.Start();??????? }??????? private readonly static Logger logger = new Logger();??????? private static Logger GetInstance()??????? {??????????? return logger;??????? }??????? //不斷處理隊列中的任務??????? private void Process()??????? {??????????? while (true)??????????? {??????????????????????????????? manual.WaitOne(); ???????????????????????????? manual.Reset(); ?????????????????????????????? Thread.Sleep(100); ????????????????????????????? Queue copy;??????????????? lock (queue)??????????????? {??????????????????? copy = new Queue(queue);??????????????????? queue.Clear();??????????????????? foreach (var action in copy)??????????????????????? action();??????????????? } ??????????? }??????? }??????? private void ExcuteAction(string log)??????? {??????????? string date = DateTime.Now.ToString();??????????? string path;??????????? if (!string.IsNullOrEmpty(Path))??????????????? path = Path + "log.txt";??????????? else??????????????? path = "log.txt";??????????? lock(queue)??????????? {???????????????????????????? queue.Enqueue(() => File.AppendAllText(path, log+" : "+date + Environment.NewLine));??????????? }??????????????????????? manual.Set();??????? } ??????????????? /// ??????? /// 將數據寫入文件中??????? /// ??????? /// 要寫入的數據??????? public static void WriteLog(string log)??????? {??????????? // WriteLog 方法只是向隊列中添加任務,執行時間極短,所以使用Task.Run。??????????? Task.Run(() =>??????????? {??????????????? GetInstance().ExcuteAction(log);??????????? });??????? } } ?兩條線程讀寫同一個對象,兩條線程都lock這個對象?用ManualResetEvent來控制讀數據的線程(Thread(Process))?當寫數據的線程(Task.Run)有數據寫入時開啟讀線程工作?這樣有可能控制并發,但測試幾次,發現幾次數據的順序有誤,但沒有漏主線程和新線程調用第三次后順序沒錯? 開Task線程調用順序完全相反,開始兩次也會有些亂!?。。。。。。。。。。?
查看完整描述

7 回答

?
12345678_0001

TA貢獻1802條經驗 獲得超5個贊

從隊列中取元素的時候不要foreach要出隊.放進去的也時候,操作private Queue queue;對象就好.不要想太多. 人家隊列類都給你做好這些東西了.你不用怪誰.
查看完整回答
反對 回復 2018-12-09
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

把WriteLog中的線程去了
查看完整回答
反對 回復 2018-12-09
?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

謝謝指點
查看完整回答
反對 回復 2018-12-09
?
慕絲7291255

TA貢獻1859條經驗 獲得超6個贊

是的,應該讓客戶端開線程做寫入
查看完整回答
反對 回復 2018-12-09
?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

Queue換成ConcurrentQueue,其他所有互斥量全部拿掉,就當做單線程處理即可。 另while(true)這種做法不好,相當于你就只考慮開始不考慮結束,如果中途需要停止最好是通過通知的方式傳過來。
查看完整回答
反對 回復 2018-12-09
?
神不在的星期二

TA貢獻1963條經驗 獲得超6個贊

謝謝指點,我也不喜歡while(true)我就是想試試線程安全和并發,我是業余自學.net的,文化有限,初中畢業,現在人也老了,估計是沒希望從事這行了。開始學的還蠻好的,后面越來越覺得要學的太多
查看完整回答
反對 回復 2018-12-09
?
蕪湖不蕪

TA貢獻1796條經驗 獲得超7個贊

@隨機哥丶: .net的學習曲線較java而言平滑一些,當然隨著了解的深入涉及的東西就會越多,這個是沒有辦法的。關于多線程,建議先不要看task和并行,直接學thread及threadpool,幾種信號量。練手也不要以有外部依賴的東西著手(比如你讀寫文件,這個實際會使場景變的更復雜),選用普通的cpu密集型計算更簡單而且也容易驗證些(比如數字的累加)。
查看完整回答
反對 回復 2018-12-09
  • 7 回答
  • 0 關注
  • 418 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號