Igavshne
Igavshne

Reputation: 697

Time consuming work and Progressbar

I have a listbox with items and the user can perform some actions on an item, such as New/Edit/Delete. However, this can take some time, and I would like to show an indeterminate progressbar while the underlying actions are being performed.

How should I handle this in .NET 4.6 & C# 6.0? According to this post I should be using Task-based Asynchronous Pattern (TAP). In the thread there are many many possible solutions.

Is that still the preferred way?

Upvotes: 1

Views: 756

Answers (2)

Raj Kumar Mishra
Raj Kumar Mishra

Reputation: 514

in C# you can use progressBar tool from toolbox to show indeterminate time.

In order to use the progressBar just drag and drop it on your form.

Now coming to main problem, you want show an indeterminant time. To show the progress in progressBar, use timer and following code:

int value = 0;
private void timer1_Tick(object sender, EventArgs e)
    {
        if (value < 100)//value at 100 can be any large integer since indeterminant time
        {
            value++;
            progressBar1.Value = value;
        }

    }

set timer1.Interval = 100;

variable value is the maximum value you set for progressBar.

Since you dont know the time, set the maximum value of progressBar to 10000 or any other big value. Now enable the timer when you enter your function(say New/Edit/Delete) and disable the timer when you exit your function

Upvotes: 0

mm8
mm8

Reputation: 169220

The first thing to understand here is that you should perform the New/Edit/Delete operations on a background thread in order to keep your UI responsive and for the ProgressBar to be able to update during the time it takes for these operations to complete.

The preferred and easiest way to off-load some work to a background thread is to use the task parallel library (TPL) and start a new task. Keep in mind that WPF controls have thread affinity though so you can only access them on the thread on which they were originally created and that is the dispatcher thread.

So you could implement this by setting the Visibility property of the ProgressBar to Visible, start a task that performs the actual New/Edit/Delete operation and then set the Visibility property back to Collapsed again once the task has finished:

C#:

pb.Visibility = Visibility.Visible;
Task.Run(()=> 
{
    //perform your long-running operation here...make sure that you don't access any UI elements
    Save();
})
.ContinueWith(task => 
{
    //this delegate will be executed back on the UI thread once the task has finished because of the scheduler returned from the TaskScheduler.FromCurrentSynchronizationContext() method...
    pb.Visibility = Visibility.Collapsed;
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());

XAML:

<ProgressBar x:Name="pb" IsIndeterminate="True" Visibility="Collapsed" />

Upvotes: 1

Related Questions