2012-03-03 86 views
1

這是場景, 我有一個應用程序每隔2秒覆蓋一個xml文件。 然後我有這個C#應用程序,每隔1-2secs讀取此文件。 這個過程中運行良好,但有些時候,我得到的錯誤說,c# - 進程無法訪問文件,因爲它被另一個進程使用

進程無法訪問文件,因爲它是由另一個進程使用

我使用XMLDocument.load方法打開和讀取xml文件。

我能做些什麼來解決這個問題? 我已經嘗試在不同的機器上運行,這是絕對隨機的,因爲在我的機器上,它運行了6個小時之前,在另一臺機器上的錯誤,

因爲我的c#程序將繼續讀取此文件,除非用戶點擊一個按鈕停止數據記錄過程

正如我希望程序繼續運行,只要用戶不停止它。 請幫忙

+0

其他過程是什麼?我們無法從這裏看到它。睡吧,我想再試一次。 – 2012-03-03 15:17:29

+0

我正在寫的文件是應用程序的問題?? – 2012-03-03 15:30:06

+0

你每秒都在讀你自己的文件?這是一種硬盤耐久性測試嗎?郵政編碼,證明您正在妥善處置作者。 – 2012-03-03 15:43:19

回答

1

當另一個應用程序寫入同一個文件時,你不能讀取文件,如果你開發了這兩個應用程序,我會推薦真正的數據庫,而不是XML文件。對於excid SQLite

但是如果你不會使用XML文件可以捕獲異常XMLDocument.load方法拋出,然後再次嘗試讀取希望其他過程與書面方式

0

該文件或者仍標記的使用進行操作系統,被另一臺計算機使用或有時被您的病毒掃描程序使用,並且沒有足夠快地釋放您的程序。您應該插入一個小的超時/延遲或使用try ... catch捕獲異常,然後再次嘗試一小段延遲。

0

當你使用一個計時器,你應該停止計時器,當你在一個文件處理,直到完成:

private void timer_Tick(object sender, EventArgs e) 
{ 
    try 
    { 
    timer.Stop(); 
    //read write whatever ... 
    } 
    catch(){} 
    timer.start(); 
} 
0

爲了避免衝突做你改寫這樣的:

  • 寫入新的XML在同一位置的臨時文件作爲舊XML
  • 新的文件重命名爲舊文件

在UNIX文件系統上,這將避免在寫入期間讀取嘗試失敗的問題。不確定窗戶,但應該工作。

6

請告訴你嘗試使用FileStream變量,它是用specialy指定constructor適當FileModeFileAccessFileShare參數實例化閱讀XmlDocument內容。您可以使用Load實現的方式將XmlDocument的內容加載到適當打開(用於反向讀取訪問的共享)文件流作爲參數的方法。

請嘗試使用下面的代碼寫入文件:

XmlDocument xmlDocument = new XmlDocument(); 
using (FileStream fileStream = new FileStream("C:\\test.xml", FileMode.Append, FileAccess.Write, FileShare.Read)) 
{ 
    xmlDocument.Load(fileStream); 
} 

,並從文件中讀取下面的代碼:

XmlDocument xmlDocument = new XmlDocument(); 
int attempts = 5; 
Exception cannotReadException = null; 
while (attempts > 0) 
{ 
    try 
    { 
     using (FileStream fileStream = new FileStream("C:\\test.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) 
     { 
      xmlDocument.Load(fileStream); 
      attempts = 0; 
     } 
    } 
    catch (Exception exception) 
    { 
     cannotReadException = exception; 
     System.Threading.Thread.Sleep(100); 
     attempts--; 
    } 
} 

if (cannotReadException != null) 
{ 
    throw cannotReadException; 
} 
+0

不,我所做的只是使用xmldocument.load – 2012-03-03 15:25:52

+0

@ Fahad.ag請嘗試打開.xml文件寫入與FileShare.Read和用FileShare.ReadWrite寫入 - 如更新的答案。 – 2012-03-03 15:58:14

+0

我會嘗試.. thnx .. – 2012-03-03 18:46:47

0

要展開什麼其他人所說,這裏是如何的例子您可以使用try catch塊來解決衝突:

private XmlDocument OpenXML(string filename, int retryCount = 0) 
{ 
    XmlDocument retval = new XmlDocument(); 

    try 
    { 
     retval.Load(filename); 
    } 
    catch 
    { 
     if (retryCount < 5) 
     { 
      retval = OpenXML(filename, retryCount + 1); 
     } 
     else 
     { 
      return null; 
     } 
    } 

    return retval; 
} 

在catch您可以根據需要添加暫停,或者增加重試次數/在達到最大嘗試次數時對其進行不同處理。

0

如前所述,您可以實現簡單的等待x(毫秒)秒重試方法。

如果您在Windows上並且有權訪問這兩個程序的源代碼,則可以使用本機Win32函數創建一個信號量來管理對該文件的訪問。有關更多詳細信息,請參閱this頁面。

+0

如果我在生成XML文件fo = _fsopen(filename,openStr,_SH_DENYNO)的應用程序上使用它,這會對嘗試實現文件的應用程序有任何影響? – 2012-03-03 15:27:59

+0

我沒有多少使用'_fsopen',但[文檔](http://msdn.microsoft.com/en-us/library/8f30b0db.aspx)讓我相信它會起作用。如果你要走這條路線,我覺得在程序中用'_SH_DENYRW'標誌調用'_fsopen'來讀程序中的XML文件和'_SH_DENYNO'標誌。 – 2012-03-03 15:34:10

+0

我應該試試這個.. – 2012-03-03 15:35:53

相關問題