2012-09-12 73 views
0

我正在開發基於.NET 4.0 C#Windows服務的應用程序(Dropbox like),該應用程序連續運行,並在內容和更新的特定文件夾上保持監視並將更改通知數據庫類似的客戶端應用程序也將被安裝在其他機器上,並且它們將對其託管機器中的相同文件夾執行適當的更新。我使用多線程和遞歸調用開發了整個應用程序,這些調用將繼續執行並通過更改來通知更改。應用程序在3小時後運行良好3小時,並引發堆棧溢出異常並崩潰。文件和文件夾同步應用程序.net C#

更具體我有9個線程,它們中的一些做以下幾項工作

1)threadFSWToDB - 寫入任何文件更改(添加,重命名,刪除),DB。

2)threadDBToUploadLogList - 在其他客戶端將從其下載文件的服務器上創建一個文件夾。

3)threadDoUpload - 將在Web服務器上傳文件。

4)threadDBToDownloadList - 將上傳由輪詢數據庫執行的更改列表。

我的問題是,這是可行的解決方案,還是我需要重新考慮我的整個應用程序的設計。如果是,那麼執行上述任務(順序或並行)的最佳方式是什麼。什麼是最基本的方法來執行這樣的任務永無止境和連續性的任務。

我的代碼如下,我不知道多少投入,以便它可以使事情清楚

Thread threadFSWToDB = new Thread(() => WriteFSWLogListToDatabase()); 


private static void WriteFSWLogListToDatabase() 
    { 
     try 
     { 
      using (var objEntities = new ShareBoxEntities()) // EF class instantiation 
      { 
// this DB class constructor call later on throws stack overflow exception not necessarily from this method 
       var objConnector = new DBConnector(objEntities); 
       var objConnector = new DBConnector(); 
       List<string> directories = objConnector.GetAllSharedDirectoryRelativePaths(); 
       if (FSWLogList != null && FSWLogList.Count() > 0) 
       { 
        for (int i = 0; i <= FSWLogList.Count - 1; i++) 
        { 

      // some file changes being written to Database 
          FSWLogList[i].SavedInDB = true; 
         } 
        } 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
    // write to event log and mail to administrator 
     } 
     finally 
     { 
      if (FSWLogList != null && FSWLogList.Count > 0) 
      { 
       FSWLogList.RemoveAll(item => item.SavedInDB == true); 
      } 
      Thread.Sleep(5000); 
      WriteFSWLogListToDatabase(); 
     } 
    } 

如果遞歸是那麼的主要原因爲什麼應用程序運行正常一段時間一個或兩個,然後一天開始顯示上述行爲

+0

如果您手動創建線程,您可能需要重新考慮。你看過並行任務庫嗎?如果沒有,你真的應該。這應該讓你開始:http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx – TimothyP

+0

不知道我們如何沒有看到任何代碼真的可以幫助。你知道異常發生在哪裏嗎?這應該可以幫助你找到麻煩的地方。聽起來就像你有一個無休止的遞歸調用,這個調用正在緩慢地遞歸併且永遠不會退出,所以最終堆棧已經耗盡。 –

+0

@TimothyP感謝您寶貴的意見,比平行執行更重要,它關於確定並行執行的點,我可以使用這些鏈接。 –

回答

0

謝謝大家寶貴的時間。

我已經找到了解決我的問題,遞歸函數調用已經被替換爲,而(真)//循環 仍在呼籲各絲 這確保我的功能,監視文件夾即使在異常發生後,try and catch也會確保它繼續執行,但並未完成其執行。我在使用時遇到的問題是(true)是函數中使用的任何資源,可用於在單獨線程上運行的其他函數,該函數通過在特定時間段內調用thread.sleep來處理。對於類似的問題,這可能不是一個通用的解決方案,但它符合我的要求,所以我希望其他人在類似的情況下實施所述解決方案之前要小心。

0

很難在不知道的細節說,但一個堆棧溢出錯誤通常意味着你會過深到你的遞歸

簡單的例子

public void ThrowStackOverflow() 
{ 
    ThrowStackOverflow() 
} 

由於沒有退出到遞歸,總是會拋出堆棧溢出。調用堆棧越來越深,直到沒有空間。

我懷疑你的程序有類似的自我指涉問題。

如果遞歸調用在恢復備份之前可能會變得太深,可能會導致堆棧溢出。

或者如果你的線程創建了自己而沒有終止,或者即使你只是在不清理它們的情況下繼續創建新線程,一些東西將不可避免地給出。

0

對我來說聽起來像你越來越線程快樂。對於DB,你有沒有線程的asynch db的BeginExecuteNonQuery。要從數據庫獲取通知,您需要查詢通知。對於擁有FileSystemWatcher的文件。我只是使用BackGroundWorker來上傳和下載文件。如果您正在上傳/下載到一臺服務器,那麼並行執行文件並不會對您有所幫助,因爲您很可能受限於帶寬。

相關問題