2

In public MainWindow() I call TestTask3(10000);. A TextBlock Text is bound to Answer in the XAML. The get is called and the initial value is displayed. I see the set call NotifyPropertyChanged. But the get is not called a second time to get the new value. I also have a button that changes Answer and that does change the TextBlock.

How to fix this or another approach? I want to keep the UI reactive and update some UI elements after a delay.

private int answser = -2;
public int Answer
{
    get { return answser; }
    set
    {
        if (answser != value)
        {
            answser = value;
            NotifyPropertyChanged("Answer");
        }
    }
}
public async void TestTask3(int delay)
{
    Debug.WriteLine($"TestTask3");
    int answer = -1;
    int i = await Task.Run(() =>
    {
        // … do compute-bound work here  
        Task.Delay(delay);
        answer = -1;
        return answer;
    });
    Debug.WriteLine($"TestTask3   {i}");
    Answer = answer;
    //return answer;
}
4
  • You shouldn’t use the same names for local variables and class fields, it’s very confusing. Have you tried putting a breakpoint in the setter and stepping through? Commented May 11, 2018 at 1:37
  • Yeah this is confusing, i cant see how on earth the property Answer would get updated twice anyway (if i'm understanding you correctly) Commented May 11, 2018 at 1:37
  • @DaveM As stated I see NotifyPropertyChanged called. That is how is see that. Commented May 11, 2018 at 1:41
  • @TheGeneral It gets updated if I change Answer in a button click event. Commented May 11, 2018 at 1:42

1 Answer 1

4

Task.Delay(delay) is awaitable method.

Following solution works for me. I took a long loop calculation and it returns me result on UI after 10 seconds. Tested and working.

public async void TestTask3(int delay)
{
    int answer = -1;
    int i = await Task.Run(async () =>
    {
        // … do compute-bound work here  
        for (int j = 0; j < 100000000; j++)
        {
            answer += j;
        }

        await Task.Delay(delay);

        //answer = -1;
        return answer;
    });
    Answer = answer;
    //return answer;
}

Usage:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    await TestTask3(10000);
}
Sign up to request clarification or add additional context in comments.

6 Comments

So it was missing an async. Not sure how that broke it but I am just glad it is fixed.
I am glad to help. Cheers :)
@paparazzo Since you should usually avoid async void methods (except event handlers), you may declare public async Task<int> TestTask3(int delay) and make it return answer. Then call it like Answer = await TestTask3(10000);
@Clemens That syntax throws a design time error for me. ` int ans = TestTask3(1000, token).Result;` is valid syntax but is hangs on that statement.
It must be int ans = await TestTask3(...). Don't use Result. See here: stackoverflow.com/q/27464287/1136211
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.