2012-01-10 50 views
2

我的應用程序在幾毫秒內最多可以處理大約100個批處理作業的請求,但實際上,這些作業請求被屏蔽爲一個作業請求。 要解決此問題,以便目前只有一個工作請求不可行。ASP.NET:激發批處理作業

我想過的解決方法是編程我的應用程序,每x毫秒只執行1個批處理作業,在這種情況下,我想到的是200毫秒,並忽略可能在200毫秒內進入的任何其他批處理作業,或者當我的批處理作業完成時。在200毫秒後,或者批量作業完成後,我的應用程序將等待並接受來自此時的1個作業請求,並且它不會處理之前可能被忽略的任何請求。一旦我的應用程序接受了另一個工作請求,它將重複上述循環。

使用.Net 4.0做這件事的最好方法是什麼?是否有任何我可以簡單遵循的鍋爐板代碼作爲指導?

更新 對不起,不清楚。我已經添加了關於我的場景的更多細節。此外,我只是意識到,我上面提出的解決方法將無法正常工作。對不起,夥計們,哈哈。這是一些背景信息。

我有一個應用程序使用指定目錄中的文件構建索引。當在此目錄中添加,刪除或修改文件時,我的應用程序將使用FileSystemWatcher監聽這些事件並重新索引這些文件。問題是大約100個文件可以被外部進程添加,刪除或修改,並且它們發生得很快,即:在幾毫秒內。我的最終目標是在外部進程發生最後一次文件更改後重新編制這些文件的索引。最好的解決方案是修改外部進程,以便在完成修改正在監聽的文件時告知我的應用程序,但目前不可行。因此,我必須創建一個解決方法。

可能解決我的問題的解決方法是等待第一個文件更改。發生第一次文件更改時,對其他後續文件更改等待200毫秒。爲什麼要200毫秒?因爲我希望並確信外部進程可以在200毫秒內執行其文件更改。一旦我的應用程序等待了200毫秒,我希望它啓動一個任務,它將重新索引這些文件,並通過另一個收聽文件更改的循環。

這樣做的最好方法是什麼?

再次,抱歉的混淆。

+0

我怎麼看不到延遲的請求的200ms將解決症狀。這聽起來像是工作流程需要重新設計,否則你會發現自己以後也會遇到同樣的情況。爲什麼不解決問題而不是解決症狀? – 2012-01-10 16:33:20

回答

0

這個問題有點太高,難以猜測。

我的猜測是您的應用程序作爲服務運行,您的請求進入您的應用程序併到達隊列中進行處理。每隔200毫秒,您就會將隊列喚醒並彈出並關閉項目進行處理。

我很困惑「掩蓋爲一個工作要求」。既然你提到你會「忽略其他任何批處理作業」,我猜你沒有安排你的代碼來接受隊列中的傳入請求。

無論如何,您通常總會有一個應用程序進程運行(您的服務),如果您選擇,您可以爲您在隊列中處理的每個項目生成一個新線程。您可以監視這需要多少CPU /內存利用率,並相應地調整點火時間(200毫秒)。

0

我可能沒有準確理解問題,但我的建議是使用單例模式來解決此問題。

使用單例方法,可以實現對對象的鎖定(訪問方法可能是沿着BatchProcessor :: GetBatchResults的行),然後鎖定對批處理作業結果對象的所有請求。批次完成後,鎖將被釋放,並且基礎對象將具有批處理作業的結果。

請記住,這是一種「變通」。可能有一個更好的解決方案,涉及到查看和更改導致多個請求進入按需處理的作業的底層業務邏輯。

更新: 下面是關於單身的鏈接信息(包括代碼示例):http://msdn.microsoft.com/en-us/library/ff650316.aspx

0

這是我的理解是,海報有一些那種坐着等待傳入的請求執行應用程序的批量作業。他在短時間內收到多個請求的問題實際上應該只是一個請求。不幸的是,他無法解決這個問題。

所以,他的解決辦法是假定一個200毫秒的時間跨度內收到的所有請求都是相同的,並且只處理這些一次。我對此的擔心是這個假設是否正確?這完全取決於發送系統和正在使用的環境。能夠做到這一點的一般想法是在處理請求時更新lastReceived日期/時間。然後,當有新的請求進入時,將當前日期/時間與lastReceived日期/時間進行比較,並且只在差值大於200 ms時才處理它。

其他可能的解決方案:

  1. 你說你不能修改發送應用程序,以便只有一個作業發送請求,但是您可以加入更多的信息給它,例如一個唯一的標識符?

  2. 你能不能從上次作業要求存儲的參數,並將其與接下來的工作要求比較和只處理他們,如果他們有什麼不同?

根據您的更新

下面是一個例子,你可以如何使用定時器等待200毫秒:

static Timer timer; 
    static int waitTime = 200; //in ms 

    static void Main(string[] args) 
    { 
     FileSystemWatcher fsw = new FileSystemWatcher(); 
     fsw.Path = @"C:\temp\"; 
     fsw.Created += new FileSystemEventHandler(fsw_Created); 
     fsw.EnableRaisingEvents = true; 

     Console.ReadLine(); 
    } 

    static void fsw_Created(object sender, FileSystemEventArgs e) 
    { 
     DateTime currTime = DateTime.Now; 

     if (timer == null) 
     { 
      Console.WriteLine("Started @ " + currTime); 

      timer = new Timer(); 
      timer.Interval = waitTime; 
      timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
      timer.Start(); 

     } 
     else 
     { 
      Console.WriteLine("Ignored @ " + currTime); 
     } 
    } 

    static void timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     //Start task here 

     Console.WriteLine("Elapsed @ " + DateTime.Now); 
     timer = null; 
    } 
+0

我認爲你對我的問題有最好的理解。我可以做1)和2)。我完全控制了批處理作業並修改了其行爲。 我提出的第一種解決方法不起作用。我有第二個解決方法,它涉及在等待200毫秒後觸發批處理作業,反對在等待200毫秒開始時觸發批處理作業。 – burnt1ce 2012-01-10 17:34:47

+0

上面的例子回答了你的問題嗎? – jzacharuk 2012-01-11 21:57:41