對於運行中的 秋色園 站點,偶爾的不經常,我都會做以下的幾件開發者該常做的事:
1:查看網站的事件日志(看看有沒有網站未發現的異常,有的話要處理)。
2:查看被捕獲的異常日志(看看都是什么情況引發的,有的話要處理)。
3:查看數據庫執行語句異常日志(看看都有啥情況)。
2:查看被捕獲的異常日志(看看都是什么情況引發的,有的話要處理)。
3:查看數據庫執行語句異常日志(看看都有啥情況)。
今天早些時候,看了下日志,對於一條比較熟悉,但一直沒怎么處理的日志,突然有了想處理掉它的想法:
log:http://www.cyqdata.com/search/cnblogs/finger+print
------------------------
Error On : 2013-3-28 5:30:18
[WriteException]:文件“D:\*\TableSchema\CYQ.Data.TableSchema_Sql.qblog.Blog_User.ts”正由另一進程使用,因此該進程無法訪問該文件。:
在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
在 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
在 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
在 System.IO.StreamWriter.CreateFile(String path, Boolean append)
在 System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
在 System.IO.StreamWriter..ctor(String path, Boolean append)
在 CYQ.Data.Tool.IOHelper.Save(String fileName, String text, Boolean isAppend)
在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
在 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
在 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
在 System.IO.StreamWriter.CreateFile(String path, Boolean append)
在 System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
在 System.IO.StreamWriter..ctor(String path, Boolean append)
在 CYQ.Data.Tool.IOHelper.Save(String fileName, String text, Boolean isAppend)
關於這個錯誤的小小解釋:
這個錯誤,其實就是對IO寫文件操作加了try
catch,然后記錄了下來,根據錯誤的直觀提示:
既然是進程性錯誤,理想當然的推想是應用程序池在回收時,產生的另一個進程,剛好寫文件時和另一個未回收完成的進程同時寫引發的異常,被記錄了。
既然是進程性錯誤,理想當然的推想是應用程序池在回收時,產生的另一個進程,剛好寫文件時和另一個未回收完成的進程同時寫引發的異常,被記錄了。
我就想了一個,通過增加進程間的互斥量,來解決多進程間並發解決方案:
static System.Threading.Semaphore _mutex =
new System.Threading.Semaphore(
1,
1,
"
IOHelper.Save
");
private static bool Save( string fileName, string text, bool isAppend)
{
try
{
if (_mutex.WaitOne( 2000, false)) // 進程間同步。
{
using (StreamWriter writer = new StreamWriter(fileName, isAppend))
{
writer.Write(text);
}
}
return true;
}
catch (Exception err)
{
Log.WriteLogToTxt(err);
}
finally
{
try
{
_mutex.Release();
}
catch
{
}
}
return false;
}
private static bool Save( string fileName, string text, bool isAppend)
{
try
{
if (_mutex.WaitOne( 2000, false)) // 進程間同步。
{
using (StreamWriter writer = new StreamWriter(fileName, isAppend))
{
writer.Write(text);
}
}
return true;
}
catch (Exception err)
{
Log.WriteLogToTxt(err);
}
finally
{
try
{
_mutex.Release();
}
catch
{
}
}
return false;
}
寫完代碼,我建了個項目,寫個Demo,測試下多進程的並發問題,代碼很簡單,一個按鈕點擊,開一個線程,運行以下這段代碼:
string path = AppDomain.CurrentDomain.BaseDirectory +
"
a.ts
";
while ( true)
{
IOHelper.Save(path, " test ", true);
}
while ( true)
{
IOHelper.Save(path, " test ", true);
}
線程一開,一個死循環,不停寫文件。
運行了一下,我查看文件是否正常創建,於是我打開那文件,看日志寫進了沒有,發現很正常寫進了,於是又回到代碼處。
然后又開了一個軟件,又點了運行,一個神奇的BUG就這樣被我觸發了:
刷的一下,拋出異常:
"文件“F:\\*\\bin\\Debug\\a.ts”正由另一進程使用,因此該進程無法訪問該文件。"
神奇的BUG的被觸發后,神一般的無解:
1:不管我怎么寫代碼,僅單線程,Lock,雙重Lock,還是Mutex,還是混合用,運行幾秒后,都拋這個異常。
2:然后我加了線程休眠,發現加到Thread.Slee( 100)以下又正常,這個正常讓我懷疑,難道文件關閉,還有延時功能?
3:通過Reflect看源碼,查了幾個基類,也沒見着特殊。。。懷疑得不到解決,納悶升級。。。
3:之后我在閃存里了點條閃存說這問題,也在QQ群發了點相似的內容。。。反正就有點納悶中無解。
4:幾小時之后,我放棄了,你妹夫的,不弄了。。神一般的簡直無解。
5:感覺東西開的太多了,我就關掉了一些,其中包括文件夾。
6:寫代碼的天性,問題不解決,又回頭折騰。
2:然后我加了線程休眠,發現加到Thread.Slee( 100)以下又正常,這個正常讓我懷疑,難道文件關閉,還有延時功能?
3:通過Reflect看源碼,查了幾個基類,也沒見着特殊。。。懷疑得不到解決,納悶升級。。。
3:之后我在閃存里了點條閃存說這問題,也在QQ群發了點相似的內容。。。反正就有點納悶中無解。
4:幾小時之后,我放棄了,你妹夫的,不弄了。。神一般的簡直無解。
5:感覺東西開的太多了,我就關掉了一些,其中包括文件夾。
6:寫代碼的天性,問題不解決,又回頭折騰。
問題失蹤了????
這回運行,一切正常了,產生多少並發也沒報那錯。。。你妹的咋回事,這么神奇????
於是我又去看了那個創建的文件有沒有問題。。。。
回頭一運行。。你妹夫的,又拋異常了。。。
於是我又去看了那個創建的文件有沒有問題。。。。
回頭一運行。。你妹夫的,又拋異常了。。。
突然意識到了什么,經過幾個拋異常,不拋異常的輪回折騰,終發現這個神般無解的的BUG:
原來是查看文件時,等於該文件被鼠標focus選定了原因,處於被forcus狀態的文件,頻繁的寫入就拋那異常了。
這BUG多無解,你妹: