0

我在后台工作人员的帮助下逐行读取外部 exe 的控制台,我将控制台的每一行分配给一个标签。问题是标签没有随控制台行更新。代码如下

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    int i = 0;
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = false;
    startInfo.FileName = EXELOCATION;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.Arguments = Program.path;
    startInfo.RedirectStandardOutput = true;
    try
    {
        // Start the process with the info we specified.
        // Call WaitForExit and then the using statement will close.
        using (exeProcess = Process.Start(startInfo))
        {
            using (StreamReader reader = exeProcess.StandardOutput)
            {
                string result;
                while ((result = reader.ReadLine()) != null)
                {
                    // object param = result;

                    e.Result = result;
                    bgWorker.ReportProgress(i++);
                }
            }
        }
    }
    catch
    {
        // Log error.
    }
}

private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    label.Text = e.ToString();
    label.Refresh();
}

我该如何解决这个问题

4

3 回答 3

2

尝试这个:

label2.Invoke(new Action(() => { label2.Text = e.ToString(); }));
label2.Invoke(new Action(() => { label2.Refresh(); }));
于 2013-10-08T12:54:36.740 回答
0

That code probably doesn't work because you're trying to update an UI element from a non-UI thread (aka background thread).

If you're using WPF, you should use the Dispatcher to request that the label be changed in the UI thread. If you're using another framework, try that framework's equivalent class.

In your ProgressChanged method, try this instead:

Application.Current.Dispatcher.BeginInvoke(
  DispatcherPriority.Background,
  () => {
    label.Text = e.ToString();
  });
于 2013-10-08T12:38:43.373 回答
0

如果这是在另一个线程中(并且您在 winforms 应用程序中),您可能需要使用Control.InvokeRequired

public void UpdateProgress (int progress)
{
  if (label.InvokeRequired)
  { 
     this.Invoke(()=> UpdateProgress(progress));
  }
  else
  {
     label.Text = progress.ToString();
  }
}

此方法检查它是否在 UI 线程上运行,如果不是,则在 UI 线程上调用自身。如果它已经在 UI 线程上,它只会更新标签。

于 2013-10-08T12:44:38.747 回答