我正在尝试创建一个包含表单进度条的线程(只是一个GIF图像)。
我在一个大方法之前就调用了StartProgress()
。基本上当线程启动时,它会加载ProgressBar表单(我想一直显示它,只是在不需要时隐藏它)并且ProgressActive
设置为true,它应该显示表单直到{{1如果为false,则应隐藏表单(直到进度再次激活)。这是我到目前为止所做的,但它冻结了我:(
ProgressActive
编辑:我正在尝试在静态类中执行此操作。
答案 0 :(得分:4)
如果使用.NET 2.0或更高版本,是否有任何理由不使用BackgroundWorker?
我之所以这么说是因为BackgroundWorker是基于事件的,所以它暴露了一个像ProgressChanged这样的事件,可以减少代码的整体大小。
答案 1 :(得分:1)
冻结是因为您试图从工作线程更改UI线程中包含的进度条。我建议将工作进程函数中的事件提升到UI线程上的处理程序。您将需要对线程上的处理程序进行调整,如下所示。
private object _lock = new object(); //should have class scope
private void ShowProgressControl(EventArgs e)
{
if (this.InvokeRequired)
{
lock (_lock)
{
EventHandler d = new EventHandler(ShowProgressControl);
this.Invoke(d, new object[] { e });
return;
}
}
else
{
//Show your progress bar.
}
}
享受!
答案 2 :(得分:1)
问题是您需要一个消息循环才能使任何UI元素正常工作。由于您是在工作线程中创建表单,因此没有消息循环在运行。要创建消息循环,您必须调用Application.Run
或Form.ShowDialog
这两个阻止呼叫。显然,该解决方案会挂断您的工作线程。
最好的办法是创建一个专门用于运行消息循环的独立线程,它可以安全地处理表单和控件。让工作线程定期将进度信息发布到可以在工作线程和UI线程之间共享的变量。然后让UI线程定期轮询(使用System.Windows.Form.Timer)共享变量并相应地更新UI。
作为旁注,我会避免使用Control.Invoke
或Control.BeginInvoke
将进度信息推送到UI线程。您的情况似乎值得采用轮询方式。倾向于推动民意调查的原因是:
Control.Invoke
强加的UI和工作线程之间的紧密耦合。答案 3 :(得分:0)
您应该在主线程上创建进度条。
确保您的繁重程序从另一个线程运行。