2013-02-11 15 views
10

मेरे पास एक ऐप है, एक चुने हुए फ़ोल्डर में * .log फ़ाइल को सुन रहा है। मैंने FileSystemWatcher का उपयोग किया।फ़ाइल.इक्सिस्ट तक प्रतीक्षा कैसे करें?

लेकिन एक समस्या है। उस फ़ाइल को लेने के लिए जिम्मेदार अन्य एप्लिकेशन निम्नलिखित कदम उठा लेता:

  1. एक * .gz फ़ाइल
  2. txt फ़ाइल (कुछ यादृच्छिक फ़ाइल नाम)
  3. बदलें उचित एक के लिए * .txt नाम में खोल दे बनाओ * .log एक्सटेंशन के साथ।

और मैं इस व्यवहार को नहीं बदल सकता।

तो मैंने * .gz, और * .txt फ़ाइलों के लिए 2 FileSystemWatcher एस बनाया। क्यूं कर? चूंकि यह ऐप कभी-कभी gz फ़ाइल को अनपैक नहीं करता है, और कभी-कभी txt फ़ाइल को अंतिम * .log फ़ाइल में पुनर्नामित नहीं करता है।

FileSystemWatcher2 txt फ़ाइल को पकड़ता है, फिर (ज्यादातर मामलों में इसे अगले 1000ms में लॉग इन करने के लिए नामित किया जाता है) मुझे यह देखने के लिए कुछ समय इंतजार करना होगा कि txt फ़ाइल मौजूद है या नहीं (यदि नहीं, तो इसे अंतिम * ।लॉग फ़ाइल)।

सवाल यह है कि यूआई फ्रीज को रोकने के लिए फ़ाइल कैसे Thread.Sleep() के बिना मौजूद है या नहीं?

मुझे उम्मीद है कि यह स्पष्ट है, अगर नहीं, तो मैं इसे बेहतर तरीके से वर्णन करने की कोशिश करूंगा। मुझे लगता है कि यह एक जटिल समस्या है।

कुछ कोड नमूना:

private void fileSystemWatcher_Created(object sender, FileSystemEventArgs e) 
{ 
    //this is for gz files in case if gz file is not unpacked automatically by other app 
    //I need to wait and check if gz was unpacked, if not, unpack it by myself, 
    //then txt watcher will catch that 
    Thread.Sleep(5000); 
    if (File.Exists(e.FullPath)) 
    { 
     try 
     { 
     byte[] dataBuffer = new byte[4096]; 
     using (System.IO.Stream fs = new FileStream(e.FullPath, 
                FileMode.Open, 
                FileAccess.Read)) 
     { 
      using (GZipInputStream gzipStream = new GZipInputStream(fs)) 
      {        
       string fnOut = Path.Combine(path_to_watcher, 
              Path.GetFileNameWithoutExtension(e.FullPath)); 

       using (FileStream fsOut = File.Create(fnOut)) 
       { 
        StreamUtils.Copy(gzipStream, fsOut, dataBuffer); 
       }        
      } 
     } 
     } 
     catch { //Ignore } 
    } 
} 

txt फ़ाइल के लिए चौकीदार:

GZ फ़ाइल के लिए चौकीदार

private void fileSystemWatcher2_Created(object sender, FileSystemEventArgs e) 
{ 
    //this is for txt file 
    Thread.Sleep(3500); 
    if (File.Exists(e.FullPath)) 
    { 
     //make my actions 
    } 
    else 
    { 
     //make my actions 
    } 
} 
+0

सभी 'Thread.Sleep()' करता है त्यागना धागा कंप्यूटर संसाधनों यह उपयोग कर रहा है, ताकि वे अन्य कार्यों के लिए इस्तेमाल किया जा सकता जारी:

यहाँ सबूत है।यह कुछ परिदृश्यों के लिए आदर्श नहीं है (क्योंकि इसमें 1 एमएस न्यूनतम ग्रैन्युलरिटी है) लेकिन जो भी आप पूरा करने की कोशिश कर रहे हैं, उसके लिए यह ठीक काम कर सकता है। –

+0

@RobertHarvey क्या आपके पास इसके लिए कुछ दस्तावेज हैं? मेरे अनुभव से, थ्रेड। नींद एक थ्रेड को आगे बढ़ने तक आगे के निर्देशों को संसाधित करने से रोकती है। एमएसडीएन से: 'थ्रेड निर्दिष्ट समय की मात्रा के लिए ऑपरेटिंग सिस्टम द्वारा निष्पादन के लिए निर्धारित नहीं किया जाएगा।' – CodingGorilla

+0

@ कोडिंग गोरिल्ला: हाँ, यह सही है। यह अन्य कार्यों के लिए थ्रेड धारण करने वाले संसाधनों को ब्लॉक करता है, और रिलीज़ करता है। यह मूल रूप से कह रहा है "मैं अगले एन मिलीसेकंड के लिए कुछ भी नहीं कर रहा हूं, इसलिए आप उस समय के दौरान कुछ और कर सकते हैं।" –

उत्तर

1

आप यूआई धागा ताला लगा के बिना नींद उपयोग कर सकते हैं, आप अनिवार्य रूप से सोने के एक अलग धागा

public event EventHandler FileCreated; 
public void CheckFileExists() 
{ 
    while(!File.Exists("")) 
    { 
    Thread.Sleep(1000); 
    } 
    FileCreated(this, new EventArgs()); 
} 

तब के रूप में इस फोन:

Thread t = new Thread(CheckFileExists); 
this.FileCreated += new EventHandler(somemethod); 
t.Start(); 

public void SomeMethod(object sender, EventArgs e) 
{ 
    MessageBox.Show("File Created!"); 
} 

या किसी अन्य पोस्ट में उल्लेख के रूप में अलग धागे के स्थान पर एक BackGroundWorker उपयोग करते हैं, कोड मैं DoWork में उल्लेख किया है डाल दिया और OnFinish घटना के लिए सुन लेकिन जैसा कि देखकर ऐसा करने के लिए बहुत अधिक काम नहीं है या तो तरीके ठीक हैं।

+0

यह शायद 'टास्क' या 'थ्रेडपूल.क्यूयूयूसर वर्कइटम' द्वारा बेहतर तरीके से संभाला जा सकता है। – CodingGorilla

+0

@ कोडिंग गोरिल्ला जाहिर है यह कार्य के लिए ओपी ढांचे पर निर्भर होगा, लेकिन हाँ शायद आपका सही: पी – LukeHennerley

+0

ठीक है, विचारों के लिए धन्यवाद। मैं उन्हें जांचूंगा। यह बहुत उपयोगी है – user1750355

3

आप एक BackGroundWorker का उपयोग फाइल सिस्टम की निगरानी के लिए कर सकते हैं - और अपने यूआई ठंड से बचने के

7

असल FileSystemWatcher बनाया नेट ही से अलग थ्रेड में कहा जाता है .. तो मूल रूप से आप कुछ नहीं करने की ज़रूरत घटना । आपका कोड ठीक है जैसा है।

class Program 
{ 
    static void Main(string[] args) 
    { 
     FileSystemWatcher fw = new FileSystemWatcher(@"C:\temp"); 
     fw.Created += fileSystemWatcher_Created; 

     Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 

     fw.EnableRaisingEvents = true; 

     Console.ReadLine(); 
    } 

    static void fileSystemWatcher_Created(object sender, FileSystemEventArgs e) 
    { 
     Console.WriteLine(Thread.CurrentThread.ManagedThreadId); 
    } 
} 
संबंधित मुद्दे