2013-04-10 113 views
0

好的我有一個應用程序根據另一個應用程序創建的文件生成一些合約。觀察文件的最佳方法

我已經實現了一個filewatcher來監視正在創建的文件,然後它會啓動一個backgroundworker進程來根據文件名創建合同。

我遇到的問題是,在後臺工作過程中,我設置EnableRaisingEvents爲false,以便應用程序不開始處理一組不同的合同,而第一的運行(這也是停止調用後臺工作,而它正在運行,因爲它無法同時運行2件事!)。

所有工作正常,其他應用程序創建一個文件,filewatcher撿起它並開始處理,問題是,當處理完成時,filewatcher重新啓用,但我認爲它不會拿起任何創建時的文件EnableRaisingEvents是錯誤的 - 因此,如果創建初始文件以生成合同的應用程序恰好在我的應用程序正在處理時創建另一個文件,它將會保留。那有意義嗎?什麼是最好的方法呢?

我曾經想過創建另一個進程,當初始合同創建完成後,將查找目錄中的其他文件,這些文件在filewatcher被禁用的時間點之間創建,如果沒有,則會重新啓用filewatcher但我想知道是否有更簡單的方法來做到這一點?

+0

你可以排隊更改的文件到列表或更好的隊列然後進程隊列順序 – 2013-04-10 12:05:55

回答

0

你可以在任務中分割你的進程。一個任務是FileRegistrator,它挑選新文件,將它們註冊到數據庫中。它一直運行,不需要EnableRaisingEvents爲false。

下一個任務是ProcessorTask(或任何名稱),它將查詢數據庫,找到第一個並處理它。它會定期查詢數據庫以查看是否註冊了新文件。

您可以在Windows服務中使用Quartz.NET調度程序來實現這個小處理器。

(我做了差不多的前一陣子,但我沒有用FileSystemWatcher的)

0

一個BlockingCollection會做到這一點。
使FileWatcher保持熱狀態並讓它添加到阻塞集合中。
消費者一次只處理一個集合。

BlockingCollection Class

class AddTakeDemo 
{ 
    // Demonstrates: 
    //  BlockingCollection<T>.Add() 
    //  BlockingCollection<T>.Take() 
    //  BlockingCollection<T>.CompleteAdding() 
    public static void BC_AddTakeCompleteAdding() 
    { 
     // here you need to synch as it would have missed any 
     // new files while the application was down 
     // yes L-Three and any files that were not yet processed 
     // clearly the existing program is an end to end synch 
     // or no synch at all as it could be nothing else 
     using (BlockingCollection<int> bc = new BlockingCollection<int>()) 
     { 

      // Spin up a Task to populate the BlockingCollection 
      using (Task t1 = Task.Factory.StartNew(() => 
      { 
       // FielSystem watcher      
       bc.Add(fille); 

      })) 
      { 

       // Spin up a Task to consume the BlockingCollection 
       using (Task t2 = Task.Factory.StartNew(() => 
       { 
        try 
        { 
         // Consume consume the BlockingCollection 
         while (true) Console.WriteLine(bc.Take()); 
         // process the file 
        } 
        catch (InvalidOperationException) 
        { 
         // An InvalidOperationException means that Take() was called on a completed collection 
         Console.WriteLine("That's All!"); 
        } 
       })) 

        Task.WaitAll(t1, t2); 
      } 
     } 
    } 
} 
+0

有趣!但是這並沒有持續下去,對吧? – 2013-04-10 13:19:01

+0

@ L-Three我沒有看到問題中的持久性要求。 – Paparazzi 2013-04-10 13:22:39

+0

不,這只是一個問題,因爲我不知道這一個。 – 2013-04-10 13:23:26