Show progress only if the background operation is long

I am developing an operation in C #, and I would like to show a modality change dialog, but only when the operation is long (for example, more than 3 seconds). I am doing my operations in the background thread.

The problem is that I do not know in advance whether the operation will be long or short.

Some software like IntelliJ has aproach timer. If the operation takes more x time, then display a dialog.

Do you think this is a good model for implementing this?

  • Wait for the user interface thread with a timer, and show the dialog there?
  • Should I DoEvents()when I show a dialogue?
+5
source share
5 answers

I will go with the first choice here with some changes:

First, run a possible lengthy operation on different threads.
Then start another thread to check the first status using the wait descriptor with a timeout to wait for it to complete. if timeout triggers show a progress bar.

Sort of:

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.
    } 
}
+4
source

Here is what I would do:

1) Use BackgroundWorker.

2) Before you call the RunWorkerAsync method, save the current time in a variable.

3) In the DoWork event, you will need to call ReportProgress. In the ProgressChanged event, check if the time has passed more than three seconds. If yes, display a dialog.

MSDN BackgroundWorker: http://msdn.microsoft.com/en-us/library/cc221403 (v = vs .95).aspx

. , . . BackgroundWorker, . .

+4

, 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();
+2

, . , ( , IntelliJ):

  • The user interface starts the background mode (in BackgroundWorker) and sets the timer for X seconds
  • When the timer expires, the user interface displays a progress dialog (if the background job is still running)
  • When the background task completes, the timer is canceled and the dialog (if any) is closed.

Using a timer instead of a separate thread is more resource efficient.

0
source

Recommended non-blocking solution and new topics:

try
{
   var t = DoLongProcessAsync();
   if (await Task.WhenAny(t, Task.Delay(1000)) != t) ShowProgress();
   await t;
}
finally
{
   HideProgress();
}
0
source

All Articles