2012-07-12 30 views
5

मैं xcopy का उपयोग कर बैकअप प्रोग्राम लिख रहा हूं और क्योंकि बहुत सी बड़ी फाइलें थोड़ी देर लगती हैं इसलिए मैं प्रगति दिखाना चाहता हूं। जब मैं मानक आउटपुट प्राप्त करने के लिए StreamReader का उपयोग करने का प्रयास करता हूं, तो जब मैं डीबग करता हूं तो यह त्रुटि संदेश होता है। "प्रक्रिया स्ट्रीम पर तुल्यकालिक और एसिंक्रोनस ऑपरेशन मिश्रण नहीं कर सकता।"मैं सी # में एक प्रक्रिया के आउटपुट को पढ़ने की कोशिश कर रहा हूं लेकिन मुझे यह संदेश मिलता है "प्रक्रिया स्ट्रीम पर तुल्यकालिक और असीमित ऑपरेशन मिश्रण नहीं कर सकता।"

public void backup_worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int loop = 1; 

     backup_worker.WorkerReportsProgress = true; 

     Process xcopy = new Process(); 
     ProcessStartInfo startinfo = new ProcessStartInfo(); 
     startinfo.CreateNoWindow = true; 
     startinfo.UseShellExecute = false; 
     startinfo.RedirectStandardError = true; 
     startinfo.RedirectStandardOutput = true; 
     startinfo.FileName = Environment.CurrentDirectory + "\\xcopy.exe"; 
     startinfo.Arguments = '"' + source + '"' + " " + '"' + target + '"' + " " + "/s /e /y"; 
     xcopy.StartInfo.RedirectStandardOutput = true; 
     xcopy.StartInfo = startinfo; 

     xcopy.Start(); 
     xcopy.BeginErrorReadLine(); 
     xcopy.BeginOutputReadLine(); 

     StreamReader sr = xcopy.StandardOutput; 

     while (loop > 0) 
     { 
      progress = sr.ReadLine(); 
      output_list.Items.Add(progress); 
     } 

     xcopy.OutputDataReceived += new DataReceivedEventHandler(backup_worker_OutputDataRecieved); 
     xcopy.ErrorDataReceived += new DataReceivedEventHandler(backup_worker_ErrorDataReceived); 
     xcopy.WaitForExit(); 
     backup_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backup_worker_RunWorkerCompleted); 
    } 

    void backup_worker_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
    { 

    } 

    void backup_worker_OutputDataRecieved(object sender, DataReceivedEventArgs e) 
    { 
    } 

    void backup_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     MessageBox.Show("Completed"); 
    } 

कृपया मदद करें। अग्रिम

उत्तर

7

समस्या धन्यवाद है कि आप दोनों सिंक्रोनस और एसिंक्रोनस उत्पादन का उपयोग कर रहे:

// Using async version here... 
xcopy.BeginOutputReadLine(); 


StreamReader sr = xcopy.StandardOutput; 

while (loop > 0) 
{ 
    // Trying to use synchronous reading here 
    progress = sr.ReadLine(); 

आप किसी एक विकल्प या अन्य, लेकिन दोनों नहीं उपयोग करने के लिए अपने एल्गोरिथ्म डिजाइन करने के लिए की जरूरत है।

3

आप तुल्यकालिक तरीके से करना चाहते हैं,

बजाय

xcopy.BeginOutputReadLine() 

उपयोग

string s = xcopy.StandardOutput.ReadToEnd() 

, चेतावनी दी है कि दोनों उत्पादन और त्रुटि के लिए है कि आप करते हैं, और उनमें से एक बहुत लंबा है, आप एक डेडलॉक हिट कर सकते हैं।

4

MSDN से नीचे टिप्पणी यह ​​बहुत स्पष्ट करना चाहिए, क्या समस्या

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

आपका कोड नीचे के रूप में तर्ज पर अधिक होना चाहिए



    public void backup_worker_DoWork(object sender, DoWorkEventArgs e) { 
     int loop = 1; 

     // This should ideally not be in the DoWork, but where you setup or create the worker 
     backup_worker.WorkerReportsProgress = true; 
     backup_worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backup_worker_RunWorkerCompleted); 
     backup_worker.WorkerSupportsCancellation = true; 

     // setup your scopy process 
     ProcessStartInfo startinfo = new ProcessStartInfo(); 
     startinfo.CreateNoWindow = true; 
     startinfo.UseShellExecute = false; 
     startinfo.RedirectStandardError = true; 
     startinfo.RedirectStandardOutput = true; 
     startinfo.FileName = Environment.CurrentDirectory + "\\xcopy.exe"; 
     startinfo.Arguments = "/s /e /y " + '"' + source + '"' + " " + '"' + target + '"' + " "; 
     Process xcopy = new Process(); 
     xcopy.StartInfo = startinfo; 
     xcopy.ErrorDataReceived += new DataReceivedEventHandler(backup_worker_ErrorDataReceived); 

     // start the xcopy and read the output 
     xcopy.Start(); 
     xcopy.BeginErrorReadLine(); 

     string copiedFileName; 
     while ((copiedFileName = xcopy.StandardOutput.ReadLine()) != null) { 
      output_list.Items.Add(copiedFileName); 
     } 

     // we should be done when here, but doesen't hurt to wait 
     xcopy.WaitForExit(); 
    } 

    void backup_worker_ErrorDataReceived(object sender, DataReceivedEventArgs e) { 
     MessageBox.Show("We have a problem. Figure what needs to be done here!"); 
    } 

    void backup_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if (e.Cancelled == true) { 
      MessageBox.Show("Canceled!"); 
     } else if (e.Error != null) { 
      MessageBox.Show("Error: " + e.Error.Message); 
     } else { 
      MessageBox.Show("Completed!"); 
     } 
    }