0

I've a button in my WPF application which function as follows

private void Button_Click(object sender, RoutedEventArgs e)
{
    loadingSpinner.Visibility = Visibility.Visible;
    DoSomeTask();    // Takes 3-4 seconds
}

My problem is the below code

loadingSpinner.Visibility = Visibility.Visible;

executes after DoSomeTask() execution is completed and all the UI related code is blocked which is written above it. I tried background workers, Parallel.Invoke and async Task but nothing worked. This just looked like a job of couple of minutes but it has been over a day and I'm not able to go past through it.

EDIT

If I try await like this

private async void Button_Click(object sender, RoutedEventArgs e)
{
    loadingSpinner.Visibility = Visibility.Visible;
    await Task.Run(() => DoSomeTask());    // Takes 3-4 seconds
}

The loadingSpinner becomes visible but code inside DoSomeTask() is never executed (which opens a webpage and performs some actions)

private void DoSomeTask()
{
    //... init variables

    driver.Navigate().GoToUrl("https://myurl.com");
    
    //.. some clicks and data filling
    driver.FindElement(By.Id("name")).SendKeys("Test");    
    driver.FindElement(By.Id("btn")).Click();
}
6
  • async is probably the way to go here. You said that it did not work - can you show us this implementation? Commented Jul 11, 2020 at 8:53
  • social.msdn.microsoft.com/Forums/vstudio/en-US/… Commented Jul 11, 2020 at 9:06
  • "loadingSpinner.Visibility = Visibility.Visible; executes after DoSomeTask() execution is completed". This is not possible in this context. Since the instruction to change the visibility comes first, it executes first. Compiler don't skip code randomly or changes execution order randomly. Do you mean something different? Asynchronous programming with async and await. Commented Jul 11, 2020 at 9:33
  • You may have to modify the DoSomeTask() too. But this depends on how it is implemented or what exactly it is doing (what you didn't show!). Commented Jul 11, 2020 at 9:38
  • Asynchronous programming. Commented Jul 11, 2020 at 9:39

1 Answer 1

0

You have two options here. Either you make the DoSomeTask() an async Task and await it or you wrap it into a Task.Run():

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    spinner.Visibility = Visibility.Visible;
    await DoSomeTask();
    spinner.Visibility = Visibility.Hidden;
}

private async Task DoSomeTask() => await Task.Delay(5000);

Or:

private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    spinner.Visibility = Visibility.Visible;
    await Task.Run(DoSomeTask);
    spinner.Visibility = Visibility.Hidden;
}

private void DoSomeTask() => Thread.Sleep(5000);
Sign up to request clarification or add additional context in comments.

6 Comments

More precisely, the DoSomeTask method in the first example must be awaitable, but not necessarily async. private Task DoSomeTask() => Task.Delay(5000); would also work.
A thread.sleep is almost always going to fail any code review nowadays. Rarely good practice. I'd prefer not to see one in an answer.
Actually in DoSomeTask, I'm loading a webpage in chrome browser through selenium and if I use await there, the spinner works fine but code inside DoSomeTask is never executed so I'm left with a blank chrome window
@Clemens you absolutely correct!
@VishalAfre That's a separate issue though, right? Are you setting UI elements in the Task?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.