2010-02-09 7 views
10

के लिए ट्रिगर करता है मेरे पास एक फाइल सिस्टम सिस्टम है जो फ़ाइल को संशोधित करते समय एक ईवेंट ट्रिगर करेगा। लॉक हटा दिए जाने के बाद मैं उस फ़ाइल से पढ़ना चाहता हूं। फिलहाल मैं ईवेंट ट्रिगर होने के बाद फ़ाइल खोलने की कोशिश कर रहा हूं, जब एक बड़ी फाइल की प्रतिलिपि बनाई जा रही है तो फाइल लॉक घटनाओं के भेजे जाने के कुछ समय बाद रहता है, जिससे फ़ाइल को पढ़ने के लिए खोला जा सकता है।फाइलसिस्टम वाटर ट्राइस्ट्रीम ओपन

कोई सुझाव?

उत्तर

6

यह वास्तव में एक डोज़ी का थोड़ा सा है, जब तक कि समस्या का स्थान महत्वपूर्ण रूप से बदल नहीं गया है, क्योंकि मुझे पिछली बार इसका सामना करना पड़ा था।

सबसे आसान तरीका फ़ाइल को खोलने का प्रयास करना है, परिणामस्वरूप IOException को पकड़ें, और यदि फ़ाइल लॉक है, तो इसे बाद में चेक करने के लिए कतार में जोड़ें। आप केवल उस फ़ाइल को संसाधित करने की कोशिश नहीं कर सकते हैं, जिसमें सभी प्रकार के मामले हैं जहां एक ही फ़ाइल के लिए कई ईवेंट जेनरेट किए जाएंगे, इसलिए प्रत्येक एकल प्राप्त ईवेंट पर एक पुनः प्रयास लूप सेट अप करने से आपदा हो सकती है। आपको इसके बजाय उन्हें कतारबद्ध करने और नियमित अंतराल पर कतार की जांच करने की आवश्यकता है।

यहाँ है कि आप इस समस्या से बाहर की मदद करनी चाहिए एक बुनियादी वर्ग टेम्पलेट है:

public class FileMonitor : IDisposable 
{ 
    private const int PollInterval = 5000; 

    private FileSystemWatcher watcher; 
    private HashSet<string> filesToProcess = new HashSet<string>(); 
    private Timer fileTimer; // System.Threading.Timer 

    public FileMonitor(string path) 
    { 
     if (path == null) 
      throw new ArgumentNullException("path"); 

     watcher = new FileSystemWatcher(); 
     watcher.Path = path; 
     watcher.NotifyFilter = NotifyFilters.FileName; 
     watcher.Created += new FileSystemEventHandler(FileCreated); 
     watcher.EnableRaisingEvents = true; 

     fileTimer = new Timer(new TimerCallback(ProcessFilesTimer), 
      null, PollInterval, Timeout.Infinite); 
    } 

    public void Dispose() 
    { 
     fileTimer.Dispose(); 
     watcher.Dispose(); 
    } 

    private void FileCreated(object source, FileSystemEventArgs e) 
    { 
     lock (filesToProcess) 
     { 
      filesToProcess.Add(e.FullPath); 
     } 
    } 

    private void ProcessFile(FileStream fs) 
    { 
     // Your code here... 
    } 

    private void ProcessFilesTimer(object state) 
    { 
     string[] currentFiles; 
     lock (filesToProcess) 
     { 
      currentFiles = filesToProcess.ToArray(); 
     } 
     foreach (string fileName in currentFiles) 
     { 
      TryProcessFile(fileName); 
     } 
     fileTimer.Change(PollInterval, Timeout.Infinite); 
    } 

    private void TryProcessFile(string fileName) 
    { 
     FileStream fs = null; 
     try 
     { 
      FileInfo fi = new FileInfo(fileName); 
      fs = fi.OpenRead(); 
     } 
     catch (IOException) 
     { 
      // Possibly log this error 
      return; 
     } 

     using (fs) 
     { 
      ProcessFile(fs); 
     } 

     lock (filesToProcess) 
     { 
      filesToProcess.Remove(fileName); 
     } 
    } 
} 

(नोट - मुझे पता है अगर यह गाड़ी है - मैं यहाँ तो यह सही नहीं हो सकता है स्मृति से याद कर रहा हूँ ।)

+0

अच्छा, मैं वही था जब मैं इंतजार कर रहा था। मैंने एक टाइम-आउट और एक प्रतीक्षा का इंतजार किया, मैं उम्मीद कर रहा था कि कुछ और सुरुचिपूर्ण था, लेकिन ओह ठीक है;) (एक महान उत्तर के प्रयास के लिए धन्यवाद दस लाख) – Matthew

संबंधित मुद्दे