2012-07-12 19 views
5

Tôi đang viết một chương trình sao lưu bằng xcopy và vì có rất nhiều tệp lớn cần một thời gian nên tôi muốn hiển thị tiến trình. Khi tôi cố gắng sử dụng StreamReader để có được đầu ra tiêu chuẩn, nó có thông báo lỗi này khi tôi gỡ lỗi. "Không thể kết hợp hoạt động đồng bộ và không đồng bộ trên luồng quy trình".Tôi đang cố gắng đọc đầu ra của một quá trình trong C# nhưng tôi nhận được thông báo này "Không thể kết hợp hoạt động đồng bộ và không đồng bộ trên luồng quy trình."

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"); 
    } 

Xin vui lòng trợ giúp. Cảm ơn trước

Trả lời

7

Vấn đề là bạn đang sử dụng cả hai đầu ra đồng bộ và không đồng bộ:

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


StreamReader sr = xcopy.StandardOutput; 

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

Bạn cần phải thiết kế thuật toán của bạn để sử dụng một lựa chọn này hay cách khác, nhưng không phải cả hai.

3

Nếu bạn muốn làm một cách đồng bộ,

thay vì

xcopy.BeginOutputReadLine() 

sử dụng

string s = xcopy.StandardOutput.ReadToEnd() 

được cảnh báo, rằng nếu bạn làm điều đó cho cả đầu ra và các lỗi, và một trong số đó quá dài, bạn có thể bị bế tắc.

4

Những lưu ý dưới đây từ MSDN nên làm cho nó rất rõ ràng, vấn đề là gì

Bạn không thể trộn lẫn các hoạt động đọc không đồng bộ và đồng bộ trên một dòng chuyển hướng. Khi luồng được chuyển hướng của Quy trình được mở ở chế độ không đồng bộ hoặc đồng bộ, tất cả hoạt động đọc tiếp theo trên luồng đó phải ở trong cùng một chế độ. Ví dụ, không theo BeginErrorReadLine với một cuộc gọi đến ReadLine trên luồng StandardError, hoặc ngược lại. Tuy nhiên, bạn có thể đọc hai luồng khác nhau ở các chế độ khác nhau. Ví dụ, bạn có thể gọi BeginErrorReadLine và sau đó gọi ReadLine cho luồng StandardOutput.

Mã của bạn nên thêm về các dòng như sau



    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!"); 
     } 
    } 

Các vấn đề liên quan