2012-07-23 41 views
0

業務案例:Web服務:只允許一個線程在同一時間執行

我有一些遠程目錄ASMX web service是拷貝/刪除/下載文件。我的WebMethod創建了執行所有這些操作的業務類的實例。在下載的情況下,我檢查哪個文件是最新的文件並下載它。一旦下載,我想立即刪除它。但是,在多線程場景中,很可能我嘗試刪除的文件已被其他某個線程刪除。

我的解決辦法:

爲了避免這樣的問題,我想Web服務在同一時間只能執行一個線程。對WebMethod的任何其他調用應等待,直到前一個線程完成下載和刪除操作。

爲此,我在商務艙中聲明瞭一個static變量。在業務類別的業務方法開始時(從WebMethod調用),我在此靜態對象上調用lock。因此,在該靜態變量(對象)上的lock未發佈之前,其他Web服務調用將不會執行業務方法中的代碼。

public class FileOperator 
{ 
    private static object locker = new object(); 

    public void DownloadAndDeleteFile(string fileName) 
    { 
     lock(locker) 
     { 
      // All business logic goes here. 
     } 
    } 
} 

WebMethod中的代碼看起來像這樣。

FileOperator fileOperator = new FileOperator(); 
     fileOperator.DownloadAndDeleteFile("File1.txt"); 

問題:

  1. 是我的解決方案是否正確?
  2. 如果是,如何只允許一個線程從web服務內執行?請注意,我只想爲此下載..上傳應該在並行線程中工作..
  3. 任何更好的解決方案?

我正在使用.NET 4.0。

回答

2

以下是我的你的需求理解:

  • 多個客戶端/線程執行Web方法,它從遠程服務器下載文件,下載後從遠程服務器中刪除下載的文件。

  • 現在各種線程可能會去相同或不同的文件下載。

  • 問題與當前的實現是,因爲你是在功能級別通用互斥鎖(鎖),所以即使一個線程想要下載一個文件,這是不被任何其他線程訪問,它必須等待因爲另一個線程正在處理另一個不同的文件,這將在擴展系統時影響性能,因爲它會同步所有客戶端,而不考慮需求。

我只想着可能的解決方案,根據要在遠程服務器上訪問的文件/資源​​,可能存在鎖定。想想以下行:

  • 在服務器方法保持靜態對象,其中每個對象被分配到不同的文件/資源​​的列表,你可以保持一個字典,它創建的靜態對象映射到一個文件。當一個線程帶有一個文件名時,它會得到相關的對象,如果它已經存在,否則創建一個新對象。現在,它試圖獲取該對象的鎖定,並且如果它是第一個線程,它將獲得一個訪問權限,否則,如果另一個線程正在同一個對象上工作,則它必須等待。 在繼續前進或快速退出互斥體之前,您可以首先檢查文件是否存在。

  • 對於所有線程都會有一個通用鎖,只需維護所有線程的字典對象的神聖性即可。因此,每個線程都可以檢查文件是否存在

//粗糙實現(你需要消毒)

公共類FileOperator { 私有靜態對象更衣室=新的對象();

private static List<object> fileObjects; 

private static Dictionary fileObjectsDictionary;  

public void DownloadAndDeleteFile(string fileName) 
{ 
    lock(locker) 
    { 
     if(fileObjects == null) 
      fileObjects = new List<object>(); 

     if(fileObjectsDictionary == null) 
      fileObjectsDictionary = new Dictionary(); 

     // check whether list contains fileName 
     // For First time Add file to a given index 
     // Create an Object using same index and add to the dictionary 
     // For any other time get the index and fetch the object from dictionary 
    } 

    lock(Dictionary Object) 
    { 
     // All business logic 
    } 
} 

}

//這樣,所有的線程不會在同一點

希望這有助於等待,

Mrinal

0

爲什麼不嘗試刪除atomiclly?

lock(obj) 
    if(IO.File.Exists(someFilePath)) 
     try 
     { 
      IO.File.Delete(someFilePath)); 
     }catch(IOException){//do nothing} 
+0

在實時這將是來電一些遠程FTP服務器,這將是相當繁重的操作。此外,讓我們說上面的代碼給了我文件ABC存在的結果,所以我嘗試刪除它,但其他一些線程可能已經刪除它,然後再發出刪除請求。整個要求有許多失敗點。例如。一個線程決定哪個是目錄中的最新文件併發出下載請求。但其他一些線程可能在此時刪除它!所以我試圖避免任何第二線程的干擾! – Learner 2012-07-23 10:28:44

+1

這就是爲什麼在存在檢查和刪除周圍存在監視器鎖定的原因。文件可能被刪除有不同的地方嗎? – Fragilerus 2012-07-23 12:02:58

相關問題