我正在尝试执行一个长时间运行的Process.Start(),并在进程执行时在屏幕上显示一个循环进度条。
我有以下几行代码:
Process p =
Process.Start(longRunningProcess);
// show the circular progress bar;
ShowHideCirProgBar(true);
// wait till the process ends execution
p.WaitForExit();
// hide the circular progress bar
ShowHideCirProgBar(false);
我是线程模型的新手,不知道如何实现上述功能。任何帮助将不胜感激。
谢谢, PJ
答案 0 :(得分:3)
不幸的是,请致电:
p.WaitForExit();
将导致程序执行被阻塞,直到生成的可执行文件退出。这将阻止WPF处理其消息泵,这反过来将阻止您的进度条正确更新。
处理此问题的常用方法是禁用UI元素,然后在后台线程中生成进程,显示进度。该过程完成后,重新启用UI元素。使用.NET 4,可能是这样的:
// Add code to disable UI, if required
DisableUI();
// Show the circular progress bar;
ShowHideCirProgBar(true);
// Wait till the process ends execution in a background thread
var task = Task.Factory.StartNew( () =>
{
Process p = Process.Start(longRunningProcess);
p.WaitForExit();
});
// Reenable the UI when the process completes...
task.ContinueWith( t =>
{
EnableUI();
// hide the circular progress bar
ShowHideCirProgBar(false);
}, TaskScheduler.FromCurrentSynchronizationContext());
或者,您可以通过BackgroundWorker执行相同的操作:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += (s, e) =>
{
Process p = Process.Start(longRunningProcess);
p.WaitForExit();
};
bw.RunWorkerCompleted += (s, e) =>
{
EnableUI();
// hide the circular progress bar
ShowHideCirProgBar(false);
};
// Add code to disable UI, if required
DisableUI();
// Show the circular progress bar;
ShowHideCirProgBar(true);
bw.RunWorkerAsync();
答案 1 :(得分:2)
我认为,您应该尝试Background worker
我认为,您希望在执行后台任务时实现一个转发用户界面。
如果这是caxe,你可以使用Background worker类,我认为这个类是最基本的类,如果你是一个非常初学的线程概念,它可以很好地工作,也不太复杂。
此类公开了您可以订阅长期运行场景的事件。
class ThreadingWithBg
{
BackgroundWorker bg = null;
public ThreadingWithBg()
{
bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
}
void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
void bg_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100000; i++)
{
Console.WriteLine(i.ToString());
}
}
public void DoLongWork()
{
bg.RunWorkerAsync();
}
}