仅当后台操作较长时才显示进度
我正在开发一个 C# 操作,我想显示一个模式进度对话框,但仅当操作很长时(例如,超过 3 秒)。我在后台线程中执行操作。
问题是我事先不知道操作会是长还是短。
某些软件(例如 IntelliJ)具有计时器方法。如果操作花费超过 x 时间,则显示一个对话框。
您认为实现这一点的好模式是什么?
- 用计时器等待 UI 线程,并在那里显示对话框?
- 显示对话框时必须使用
DoEvents()
吗?
I'm developing a C# operation and I would like to show a modal progress dialog, but only when an operation will be long (for example, more than 3 seconds). I execute my operations in a background thread.
The problem is that I don't know in advance whether the operation will be long or short.
Some software as IntelliJ has a timer aproach. If the operation takes more than x time, then show a dialog then.
What do you think that is a good pattern to implement this?
- Wait the UI thread with a timer, and show dialog there?
- Must I
DoEvents()
when I show the dialog?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这就是我要做的:
1)使用BackgroundWorker。
2) 在调用 RunWorkerAsync 方法之前,将当前时间存储在变量中。
3) 在DoWork 事件中,您需要调用ReportProgress。在 ProgressChanged 事件中,检查时间是否已超过三秒。如果是这样,则显示对话框。
以下是 BackgroundWorker 的 MSDN 示例: http: //msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
注意:总的来说,我同意 Ramhound 的观点 评论。只是始终显示进度。但如果你不使用BackgroundWorker,我会开始使用它。它会让你的生活更轻松。
Here's what I'd do:
1) Use a BackgroundWorker.
2) In before you call the method RunWorkerAsync, store the current time in a variable.
3) In the DoWork event, you'll need to call ReportProgress. In the ProgressChanged event, check to see if the time has elapsed greater than three seconds. If so, show dialog.
Here is a MSDN example for the BackgroundWorker: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
Note: In general, I agree with Ramhound's comment. Just always display the progress. But if you're not using BackgroundWorker, I would start using it. It'll make your life easier.
我将在此处选择第一个选择并进行一些修改:
首先在不同的线程中运行可能的长时间运行的操作。
然后运行另一个线程,通过等待句柄检查第一个状态,并超时等待其完成。如果超时触发,则会显示进度条。
像这样的东西:
I will go with the first choice here with some modifications:
First run the possible long running operation in different thread.
Then run a different thread to check the first one status by a wait handle with timeout to wait it for finish. if the time out triggers there show the progress bar.
Something like:
假设您有
DoPossibilityLongOperation()
、ShowProgressDialog()
和HideProgressDialog()
方法,您可以使用 TPL 为您完成繁重的工作:Assuming you have a
DoPossiblyLongOperation()
,ShowProgressDialog()
andHideProgressDialog()
methods, you could use the TPL to do the heavy lifting for you:推荐的非阻塞解决方案并且没有新线程:
Recommended non-blocking solution and no new Threads:
我会将进度对话框与后台活动分开,以将我的 UI 逻辑与应用程序的其余部分分开。因此,顺序将是(这与 IntelliJ 所做的基本相同):
使用计时器而不是单独的线程会更节省资源。
I would keep the progress dialog separate from the background activity, to separate my UI logic from the rest of the application. So the sequence would be (This is essentially the same as what IntelliJ does):
Using a timer instead of a separate thread is more resource-efficient.
我从 Jalal Said 答案中得到了这个想法。我要求需要超时或取消进度显示。我没有将附加参数(取消令牌句柄)传递给
WaitAny
,而是将设计更改为依赖于Task.Delay()
像这样使用它;
I got the idea from Jalal Said answer. I required the need to timeout or cancel the progress display. Instead of passing an additional parameter (cancellation token handle) to the
WaitAny
I changed the design to depend onTask.Delay()
Use it like so;