2011-01-16 2 views
1

Я только начинаю искать делегатов и асинхронные обратные вызовы, но с некоторыми трудностями понимают это. У меня есть эта форма и вы не хотите ждать строки x = SR.ReadToEnd(); для завершения, я хочу получить обратную связь в форме со строкой x = _streamreader.ReadLine(); после каждого обновления в экземпляре cmd.Получение обратной связи в основной поток темы async C#?

Как мне это сделать?

С моей точки зрения, я холодный, создаю делегат, который содержит х? и возвращает это в основной поток каждый раз, когда он обновляется?

using System; 
using System.Windows.Forms; 
using System.Diagnostics; 

namespace WindowsFormsApplication2 
{ 
    public partial class Form1 : Form 
    { 
     private string _command = "tracert www.google.com"; 
     private string _application = "cmd"; 
     private string _exitCommand = "exit"; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      richTextBox1.Text += GetTrace(); 
     } 

     private string GetTrace() 
     { 
      Process myprocess = new Process(); 
      ProcessStartInfo StartInfo = new ProcessStartInfo(); 
      StartInfo.FileName = _application; 
      StartInfo.RedirectStandardInput = true; 
      StartInfo.RedirectStandardOutput = true; 
      StartInfo.UseShellExecute = false; 
      StartInfo.CreateNoWindow = true; 
      myprocess.StartInfo = StartInfo; 
      myprocess.Start(); 
      System.IO.StreamReader SR = myprocess.StandardOutput; 
      System.IO.StreamWriter SW = myprocess.StandardInput; 
      SW.WriteLine(_command); 
      SW.WriteLine(_exitCommand); 
      string x = SR.ReadToEnd(); 
      SW.Close(); 
      SR.Close(); 
      return x; 
     } 
    } 
} 

ОБНОВЛЕНИЕ: от кончика ERNO я создал объект для хранения значения, и обновления в цикле в то время, а затем я прочитал объект в случае обновления. Это хороший способ сделать это? или есть более чистый способ сделать это?

using System; 
using System.Windows.Forms; 
using System.Diagnostics; 

namespace WindowsFormsApplication2 
{ 
    public class StringHolder 
    { 
     public string Buffer { get; set; } 
    } 

    public partial class Form1 : Form 
    { 
     private string x; 
     private const string Command = "tracert www.google.com"; 
     private const string Application = "cmd"; 
     private const string ExitCommand = "exit"; 
     readonly StringHolder sh = new StringHolder(); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object _sender, EventArgs _e) 
     { 
      GetTrace(); 
     } 

     private void GetTrace() 
     { 
      backgroundWorker1.RunWorkerAsync(); 
     } 

     private void backgroundWorker1_DoWork(object _sender, System.ComponentModel.DoWorkEventArgs _e) 
     { 
      Process myprocess = new Process(); 
      ProcessStartInfo StartInfo = new ProcessStartInfo(); 
      StartInfo.FileName = Application; 
      StartInfo.RedirectStandardInput = true; 
      StartInfo.RedirectStandardOutput = true; 
      StartInfo.UseShellExecute = false; 
      StartInfo.CreateNoWindow = true; 
      myprocess.StartInfo = StartInfo; 
      myprocess.Start(); 
      System.IO.StreamReader _streamreader = myprocess.StandardOutput; 
      System.IO.StreamWriter _streamwriter = myprocess.StandardInput; 
      _streamwriter.WriteLine(Command); 
      _streamwriter.WriteLine(ExitCommand); 
      while (_streamreader.EndOfStream == false) 
      { 
       lock(sh) 
       { 
        sh.Buffer = _streamreader.ReadLine(); 
       } 

       backgroundWorker1.ReportProgress(1, null); 
      } 
      _streamwriter.Close(); 
      _streamreader.Close(); 
     } 

     private void backgroundWorker1_ProgressChanged(object _sender, System.ComponentModel.ProgressChangedEventArgs _e) 
     { 
      lock(sh) 
      { 
       if (sh.Buffer != x) 
       { 
        richTextBox1.Text += "\n" + sh.Buffer; 
       } 
       x = sh.Buffer; 
      } 
     } 
    } 
} 

ответ

2

Похоже, что свойство Buffer используется только для сообщения о прогрессе. Если это действительно так, я просто передаю строку, которая была прочитана как второй параметр в вызове ReportProgress. Затем в обработчике ProgressChanged его можно получить с помощью свойства UserState. Это избавиться от буфера и связанного с замком

.............. 
sh.Buffer = _streamreader.ReadLine(); 
......... 
private void backgroundWorker1_ProgressChanged(object _sender, System.ComponentModel.ProgressChangedEventArgs _e) 
    { 

     richTextBox1.Text += "\n" + _e.UserState; 
    } 
1

Вы считаете BackgroundWorker? Использование события ReportProgress сделает это очень просто.

Событие ReportProgress допускает передачу целого числа (прогресс), но вы можете заполнить объект некоторой информацией (строкой?) И использовать событие ReportProgress для предупреждения основного потока. Убедитесь, что вы используете соответствующие блокировки при чтении/записи объекта.

+0

да я даже смотреть, чтобы с помощью фона рабочего, но dident удалось выяснить, как передать информацию я необходимую обратно в случае ReportProgress – Darkmage

+0

я сделал обновить в своем ответе новый код – Darkmage

Смежные вопросы