C#进度条不配合
我遇到了一个非常奇怪的情况。这应该很简单,但我不知道为什么会发生 我有一个字幕进度条设置为visible=false,因为它是初始状态。然后在运行时的某个时刻,我调用了我的一个函数,在调用它之前,我将PB设置为visible=true,在函数结束后,我将其设置回visible=false。再简单不过了C#进度条不配合,c#,progress-bar,C#,Progress Bar,我遇到了一个非常奇怪的情况。这应该很简单,但我不知道为什么会发生 我有一个字幕进度条设置为visible=false,因为它是初始状态。然后在运行时的某个时刻,我调用了我的一个函数,在调用它之前,我将PB设置为visible=true,在函数结束后,我将其设置回visible=false。再简单不过了 If (something) { pb.visible=true; runMyfunction(x, x, x, x,); pb.visible=false; } 问题是我从来没有见
If (something)
{
pb.visible=true;
runMyfunction(x, x, x, x,);
pb.visible=false;
}
问题是我从来没有见过PB。如果我注释掉我的函数并remove=false,PB就会出现,但一旦我把函数放回那里,PB就再也不会出现
我尝试过各种方法。使用If语句确保在它接触函数之前获得一个进度条,并且它仍然隐藏PB
我错过什么了吗?这似乎不应该如此复杂。显示对象、运行函数、隐藏对象。对吧?:) 在
runMyFunction()
方法调用Application.DoEvents()
中强制应用程序重新绘制并处理windows消息循环:
e、 g
这可能是因为您的函数正在运行,并且完成得太快,以至于您无法看到条形图。我知道这种情况以前发生过几次。这是因为您的函数正在绑定UI线程。将ProgressBar设置为visible需要释放UI线程来绘制它,但是您需要继续处理函数,这永远不会给它绘制时间 您可以通过调用:来解决这一问题,它将停止处理您的方法足够长的时间,以处理一些windows消息(并进行相关绘图)
Application.DoEvents
的一个大问题是,假设您正在从runMyfunction()
更新进度条,则必须不断调用Application.DoEvents
以允许PB绘制,否则您将看到它,但您永远看不到它的更新
更好的解决方案是将
runMyfunction()
调用推送到后台线程,并从那里异步更新进度条。这当然要复杂得多,但有助于获得更好的用户体验。我的猜测是myRunFunction()
在UI线程上运行
在调用RunWorkerAsync
并在RunWorkerCompleted
事件中停止它之前,请尝试在内部运行它并启动ProgressBar
编辑代码示例:
public class SomeClass
{
private BackgroundWorker _myFunctionBackgroundWorker;
private SomeProgressBar pb;
public SomeClass()
{
_myFunctionBackgroundWorker = new BackgroundWorker();
_myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork;
_myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted;
pb.visible = true;
_myFunctionBackgroundWorker.RunWorkerAsync();
}
private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
runMyfunction();
}
private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pb.visible = false;
}
}
这是winforms或asp.net或WPF还是什么?您指的是asp.net的winforms进度条吗?BackgroundWorker可能非常适合这种情况。它封装了许多您需要的方法。这非常好,因为它确实解决了问题。但是,由于在函数运行约10秒时,我的应用程序仍然被占用,因此字幕从不移动。我只是做了一个简单的路由,在函数运行时显示字幕,然后在最后删除它。我要用backgroundworker试试ROBOlav的建议。效果很好!非常感谢。但有一个问题。我的函数有几个catch语句,当它遇到这些语句时,我会得到一个跨线程错误。我想出于某种原因,这些都没有封装在后台工作人员启动的原始线程中。我能修好吗?没关系,我知道了。我不得不重新安排我的函数,但一旦我把我所有的结果都交给e.Result,一切都很完美!再次感谢您使用backgroundworker为我提供了正确的设置方法。
public class SomeClass
{
private BackgroundWorker _myFunctionBackgroundWorker;
private SomeProgressBar pb;
public SomeClass()
{
_myFunctionBackgroundWorker = new BackgroundWorker();
_myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork;
_myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted;
pb.visible = true;
_myFunctionBackgroundWorker.RunWorkerAsync();
}
private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
runMyfunction();
}
private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pb.visible = false;
}
}