2010-12-27 9 views
5

मेरे पास एक ऐसा एप्लिकेशन है जो अन्य अनुप्रयोगों को लॉन्च करता है, और उसके बाद एक विशिष्ट डेटा फ़ाइल बनाने के लिए प्रतीक्षा करता है (यह एक समय में एक एप्लिकेशन देखता है)। प्रत्येक बार जब कोई एप्लिकेशन लॉन्च होता है तो यह एक विशिष्ट फ़ाइल को बनाने के लिए एक विशिष्ट निर्देशिका देखता है। मैं ऐसा करने के लिए FileSystemWatcher का उपयोग कर रहा हूं (इसे निर्देशिका में सेट करें, फिर सही फ़ाइल नाम के लिए फ़िल्टर करें)। यह पहली बार (हमेशा) महान काम करता है, लेकिन दूसरा एप्लीकेशन लॉन्च कभी भी घटना को नहीं चलाता है। घटना को आग लगने का एकमात्र तरीका यह है कि यदि मैं इवेंट हैंडलर में ब्रेक-पॉइंट डालता हूं, या यदि मेरे पास थ्रेड है। ईवेंट हैंडलर में स्लीप कमांड। यह मेरे लिए बहुत अजीब लगता है ... क्या कुछ दौड़ की स्थिति है जिसके बारे में मुझे पता नहीं है? कोड यहाँ है। ध्यान दें मेरे पास एक थ्रेड है। नींद (500)। इस लाइन के साथ कोड हर बार काम करता है। इसके बिना असफल हो जाएगा। मैं वास्तव में एक नींद कमांड पर भरोसा नहीं कर रहा हूँ। मुझे यकीन नहीं है कि कौन सी हालत का कारण बन जाएगा जो काम नहीं करेगा।फाइलसिस्टम वाटर - घटना दूसरी बार गोलीबारी नहीं कर रही है

public static void watchFiles(string path) 
    { 
     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Path = path; 
     watcher.Created += new FileSystemEventHandler(watcher_Handler); 
     watcher.EnableRaisingEvents = true; 
    } 

    public static void watcher_Handler(object sender, FileSystemEventArgs e) 
    { 
     //Hack - the sleep allows the second and third application to be caught by this event 
     Thread.Sleep(500); 

     switch (e.ChangeType.ToString()) 
     { 
      case "Changed": 
       break; 
      case "Deleted": 
       break; 
      case "Created": 
       if (e.Name == "log.dat") 
       { 
        parseDataFile(); 
        moveHTMLtoLMS(); 

       } 
       break; 
      default: 
       break; 
     } 
    } 

किसी को जानते हो क्यों मुझे लगता है कि नींद है (या तोड़ने सूत्री) दूसरी बार काम करने के लिए कोड प्राप्त करने के लिए की जरूरत है?

+0

यह कोड मुझे ठीक दिखता है। – Simone

+5

नोट: आपको स्विच में 'e.ChangeType.ToString()' का उपयोग करने की आवश्यकता नहीं है, बस 'e.ChangeType' पर स्विच करें और' ChangeType.XXX 'केस बनाएं। यह दृढ़ता से टाइप किया गया है और कम त्रुटि प्रवण बनाता है। – Femaref

+0

फाइल सिस्टम वॉचर में बहुत सी चेतावनियां हैं। http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.oncreated.aspx यह कहा गया, क्या आप सुनिश्चित हैं कि विभिन्न दर्शक एक ही निर्देशिका नहीं देख रहे हैं? – NotMe

उत्तर

1

System.IO.FileSystemWatcher वर्ग के प्रलेखन के अनुसार:

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

ऐसा हो सकता है कि घटना पर्याप्त तेज़ी से उपभोग नहीं की जा रही है और आंतरिक बफर सभी अधिसूचनाओं को संभालने के लिए पर्याप्त नहीं है। डिफ़ॉल्ट रूप से, दर्शक FileName, DirectoryName, LastWrite अधिसूचनाओं को संभालता है फिर भी आप केवल निर्माण ईवेंट (फ़ाइल और निर्देशिका दोनों) का उपभोग करते हैं। क्या आपके आवेदन त्वरित उत्तराधिकार में चल रहे हैं? मैं आपके अनुप्रयोगों के आमंत्रण (ईवेंट हैंडलर के बजाए) के बीच देरी डालने का प्रयास करता हूं, अधिक विशिष्ट फ़िल्टर (केवल FileName अधिसूचना का उपयोग करें या केवल Filter संपत्ति का उपयोग करके लॉग फ़ाइलों के लिए देखें), आंतरिक बफर आकार या किसी भी संयोजन को बढ़ाएं उपर्युक्त में से। मुझे लगता है कि आपकी समस्या को ठीक करना चाहिए।

+1

अन्य अनुप्रयोग त्वरित उत्तराधिकार में नहीं चल रहे हैं। मैं एक ही परिणाम के साथ विभिन्न अनुप्रयोगों को लॉन्च करने के बीच कुछ सेकंड या कुछ मिनट इंतजार कर सकता हूं। – cwo

+0

@cwo: यदि आप अन्य बातों का उल्लेख करते हैं तो आप देरी से बाहर निकलने में सक्षम हो सकते हैं। –

0

आप केवल एक "निर्मित" ईवेंट की सूची दे रहे हैं। आपको अन्य सभी को भी सुनने की ज़रूरत है - ऑन चेंज, ऑनडिलेटेड - http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx

संपादित करें: अधिकांश प्रोग्राम पहले से मौजूद होने पर फ़ाइल "निर्माण" नहीं करेंगे। आप फ़ाइलमोन (अब प्रोसेस मॉनिटर - http://technet.microsoft.com/en-us/sysinternals/bb896645) का उपयोग करके यह देखने के लिए कर सकते हैं कि प्रत्येक प्रोग्राम आपके फ़ाइल के साथ कौन से संचालन करता है।

+0

बनाई गई घटना केवल एकमात्र है जिसमें मुझे रूचि है। स्विच स्टेटमेंट में अन्य मामले केवल शुरुआत में फाइल सिस्टम सिस्टम का परीक्षण करने के लिए थे। जब फ़ाइल बनाई जाती है तो मुझे इसे पार्स करने की आवश्यकता होती है। जिस तरह से यह फाइलों को काम करता है उसे कभी भी बदला नहीं जाएगा, हटाया जाएगा, या नाम बदल दिया जाएगा (या यदि वे मुझे इसकी परवाह नहीं करते हैं)। – cwo

+0

अपनी मान्यताओं को सत्यापित करने के लिए प्रक्रिया मॉनिटर का उपयोग करने का प्रयास करें - मुझे संदेह है कि अन्य प्रोग्रामों द्वारा किए गए "निर्माण" ऑपरेशन नहीं हैं ... या कम से कम आप यह सुनिश्चित करने के लिए जान लेंगे कि समस्या आपके कोड के साथ है, अधिसूचनाओं के साथ नहीं। –

+0

मैंने सत्यापित किया है कि फ़ाइल सही स्थान पर बनाई जा रही है। मैं प्रक्रिया एक्सप्लोरर का उपयोग कर रहा हूँ। लेकिन मैं सिर्फ प्रश्न में निर्देशिका खोल सकता हूं और देख सकता हूं कि फ़ाइल बनाई जा रही है। – cwo

0

मुझे यहां एक ही समस्या का सामना करना पड़ रहा है (विंडोज एक्सपी चल रहा है)। आपका हैक समस्या हल करता है। मैं कुछ नोट्स जोड़ना चाहता हूं जो प्रासंगिक हो सकते हैं।

मेरे मामले में फ़ाइल नाम हमेशा एक जैसा है: सी: \ blah.txt बनाया गया है, हटाया गया है, बनाया गया है और आगे। इसके अलावा, मैं अपने आवेदन को छिपाने के लिए एक चाल का उपयोग कर रहा:

Integrator.StartMonitor(); // Start the file monitor! 

Form f = new Form(); 
f.ShowInTaskbar = false; 
f.ShowIcon = false; 
f.StartPosition = FormStartPosition.Manual; 
f.Location = new Point(-32000, -32000); 

f.Show(); 
f.Hide(); 

Application.Run(); 

मेरे फ़ाइल द्रष्टा डिबग मोड में काम करता है या जब मैं तुम्हारा नींद हैक जोड़ें। यह निश्चित रूप से FileSystemWatcher में एक बग की तरह दिखता है।

1
public static void watchFiles(string path) 
{ 
    FileSystemWatcher watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.Created += new FileSystemEventHandler(watcher_Handler); 
    watcher.EnableRaisingEvents = true; 
} 

watcher चर इस विधि के अंत में कचरा संग्रह के लिए योग्य है। स्थानीय चर होने के बजाय, इसे कक्षा-स्तर के सदस्य के रूप में बनाएं:

private static FileSystemWatcher watcher; 

public static void watchFiles(string path) 
{ 
    if (watcher != null) 
    { 
     watcher.EnableRaisingEvents = false; 
     watcher.Created -= new FileSystemEventHandler(watcher_Handler); 
    } 

    watcher = new FileSystemWatcher(); 
    watcher.Path = path; 
    watcher.Created += new FileSystemEventHandler(watcher_Handler); 
    watcher.EnableRaisingEvents = true; 
} 
संबंधित मुद्दे