Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show progress only if a background operation is long

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?
like image 893
Daniel Peñalba Avatar asked Aug 04 '11 14:08

Daniel Peñalba


3 Answers

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.

like image 56
JP Richardson Avatar answered Nov 15 '22 03:11

JP Richardson


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:

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.
    } 
}
like image 21
Jalal Said Avatar answered Nov 15 '22 02:11

Jalal Said


Assuming you have a DoPossiblyLongOperation(), ShowProgressDialog() and HideProgressDialog() methods, you could use the TPL to do the heavy lifting for you:

var longOperation = new Task(DoPossiblyLongOperation).ContinueWith(() => myProgressDialog.Invoke(new Action(HideProgressDialog)));

if (Task.WaitAny(longOperation, new Task(() => Thread.Sleep(3000))) == 1)
    ShowProgressDialog();
like image 2
Allon Guralnek Avatar answered Nov 15 '22 03:11

Allon Guralnek