Reputation:
I have an issue with ProgressBar being actualized in a separated UI thread...
I have in my program lots of methods, in which I would like to start and stop a progress bar.
Therefore, I put a UI component ProgressBar in my UI and made a model for it, which (after bindings) works fine when called/used standalone in my model classes (i am not working in code behind).
The problem arises when I set my Progress
model property as indeterminate and then call some other methods: the whole works synchronously and the progressbar gets moving only at the end when exiting the main method.
Here an example of what I want to achieve:
public void MyMethod1()
{
StartProgress();
NormalSubMethod1();
NormalSubMethod2();
(...)
EndProgress();
}
public void MyMethod2()
{
StartProgress();
NormalSubMethod5();
(...)
EndProgress();
}
and here is how my StartProgress()
looks like, with what i've tried without success:
public async void StartProgress()
{
//Task.Run(() => { Progress.IsIndeterminate = true; });
//await Task.Run(() => Progress.IsIndeterminate = true); // starts moving
}
public async void StopProgress()
{
Progress.IsIndeterminate = false; // stops moving
}
I know this has to be a problem of not correctly using the async
, await
and Task
things, but I could not yet get it to work. May anyone please help me providing me a hint on how can I accomplish this?
Upvotes: 0
Views: 1026
Reputation: 2299
Your NormalSubMethod-s
should be asynchronous themselves. Below is an example how it can works. Please take a look how async/await are used here.
XAML
<StackPanel>
<ProgressBar
x:Name="progress"
Width="100"
Height="30"/>
<Button Content="Button"
Width="60"
Height="30" Click="Button_Click"
/>
<TextBlock
TextWrapping="Wrap"
x:Name="textBlock" />
</StackPanel>
Code
private async void Button_Click(object sender, RoutedEventArgs e)
{
StartProgress();
await MyMethod();
StopProgress();
}
private async Task MyMethod()
{
textBlock.Text += "MyMethod start" + Environment.NewLine;
await Task.Delay(3000); // here we are imitating the real work
textBlock.Text += "MyMethod end" + Environment.NewLine;
}
public void StartProgress()
{
progress.IsIndeterminate = true;
textBlock.Text += "StartProgress" + Environment.NewLine;
}
public void StopProgress()
{
progress.IsIndeterminate = false;
textBlock.Text += "StopProgress" + Environment.NewLine;
}
Edit
You can also wrap your existing synchronous method with Task.Run to run it asynchronously.
private async Task MyMethod()
{
textBlock.Text += "MyMethod start" + Environment.NewLine;
await Task.Run(() => NormalSubMethod1());
textBlock.Text += "MyMethod end" + Environment.NewLine;
}
private void NormalSubMethod1()
{
long n = 0;
for (var i = 0; i < 1e9; i++)
{
n++;
}
}
Upvotes: 2