我在后台工作者的帮助下逐行读取外部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();
}
我该如何解决这个问题
答案 0 :(得分:2)
试试这个:
label2.Invoke(new Action(() => { label2.Text = e.ToString(); }));
label2.Invoke(new Action(() => { label2.Refresh(); }));
答案 1 :(得分:0)
该代码可能无效,因为您尝试从非UI线程(也称为后台线程)更新UI元素。
如果您正在使用WPF,则应使用Dispatcher
请求在UI线程中更改标签。如果您正在使用其他框架,请尝试该框架的等效类。
在ProgressChanged方法中,请尝试以下方法:
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
() => {
label.Text = e.ToString();
});
答案 2 :(得分:0)
如果这是在另一个线程中(并且您在winforms应用程序中),则可能需要使用Control.InvokeRequired
public void UpdateProgress (int progress)
{
if (label.InvokeRequired)
{
this.Invoke(()=> UpdateProgress(progress));
}
else
{
label.Text = progress.ToString();
}
}
此方法检查它是否在UI线程上运行,如果不是,则在UI线程上调用自身。如果它已经在UI线程上,它只是更新标签。