我正在开发C#操作,我只想显示一个模式进度对话框,但只有在操作很长(例如超过3秒)时才会显示。我在后台线程中执行我的操作。只有在后台操作很长的情况下才显示进度
问题是,我不知道操作是长期还是短期。
一些软件如IntelliJ有一个定时器aproach。如果该操作花费的时间超过x次,则会显示一个对话框。
你认为这是一个很好的模式来实现这个?
- 用计时器等待UI线程,并在那里显示对话框?
- 必须我
DoEvents()
当我显示对话框?
我正在开发C#操作,我只想显示一个模式进度对话框,但只有在操作很长(例如超过3秒)时才会显示。我在后台线程中执行我的操作。只有在后台操作很长的情况下才显示进度
问题是,我不知道操作是长期还是短期。
一些软件如IntelliJ有一个定时器aproach。如果该操作花费的时间超过x次,则会显示一个对话框。
你认为这是一个很好的模式来实现这个?
DoEvents()
当我显示对话框?我将与第一选择去这里有一些修改:
首先运行在不同的线程可能长时间运行的操作。
然后运行一个不同的线程,通过超时的等待句柄来检查第一个状态,以等待完成。如果超时触发,则显示进度条。
喜欢的东西:
private ManualResetEvent _finishLoadingNotifier = new ManualResetEvent(false);
private const int ShowProgressTimeOut = 1000 * 3;//3 seconds
private void YourLongOperation()
{
....
_finishLoadingNotifier.Set();//after finish your work
}
private void StartProgressIfNeededThread()
{
int result = WaitHandle.WaitAny(new WaitHandle[] { _finishLoadingNotifier }, ShowProgressTimeOut);
if (result > 1)
{
//show the progress bar.
}
}
这里就是我想要做的:
1)使用一个BackgroundWorker。
2)在调用RunWorkerAsync方法之前,将当前时间存储在一个变量中。
3)在DoWork事件中,您需要调用ReportProgress。在ProgressChanged事件中,检查时间是否已超过三秒。如果是这样,显示对话框。
这里是BackgroundWorker的一个MSDN例子:http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
注:一般情况下,我同意Ramhound的评论。只要始终显示进度。但是如果你不使用BackgroundWorker,我会开始使用它。它会让你的生活更轻松。
我会将进度对话框与后台活动分开,以将我的UI逻辑与应用程序的其余部分分开。因此,顺序将是(这是基本相同什么的IntelliJ一样):
使用定时器,而不是一个单独的线程是多个资源效率高达。
假设你有一个DoPossiblyLongOperation()
,ShowProgressDialog()
和HideProgressDialog()
方法,你可以使用TPL做繁重的你:
var longOperation = new Task(DoPossiblyLongOperation).ContinueWith(() => myProgressDialog.Invoke(new Action(HideProgressDialog)));
if (Task.WaitAny(longOperation, new Task(() => Thread.Sleep(3000))) == 1)
ShowProgressDialog();
而不是Thread.Sleep,我会建议Task.Delay,以免整个线程进入睡眠状态(多个任务可能在同一个线程上运行)。 – MCattle
@MCattle:是的。在编写这个答案的时候,Task.Delay并不存在于框架中,并且使用System.Threading.Timer会使事情变得复杂,以致于无法证明我试图展示的简单原则。 –
推荐非阻塞的解决方案,没有新的主题:
try
{
var t = DoLongProcessAsync();
if (await Task.WhenAny(t, Task.Delay(1000)) != t) ShowProgress();
await t;
}
finally
{
HideProgress();
}
你为什么不简单总是显示进度。如果它的任务很短,那么进度条就会被填满并显示很短的时间。例如Office总是在底部显示加载进度条,即使在小文档中也是如此。 –
操作快时看到闪烁的对话框(毫秒)很烦人。 –