Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

c# - Why don't delays work when I'm attempting to flash an error message?

Problem: I'm working on a calculator as my first MVVM application and have come across an interesting problem that I would like to understand better. My noob problem is that I'm trying to flash an error message for an invalid input--in this case I don't want the user to use the negate operator in an invalid location. In order to flash the message across the screen, I'm saving the display in another variable, setting the display to say "Invalid Operation", then I'd like to delay for half a second and reset the display to what it was before (from the temp variable). My problem is that the display variable gets set but the actual display doesn't update to show the error message, no matter how long the delay is.

I've tried both blocking (Thread.Sleep) and non-blocking delays (Task.Delay) within the function, writing separate functions to set and reset the display, and delaying within the Negate function instead, but none of these attempts allow the display to update. The display works as expected when adding and deleting characters in other parts of the code, so I don't think there's an issue with that.

Is this some sort of piping issue (the delay function actually starts before it can call the Display property) or something else entirely? I've checked other posts on here and those solutions don't seem to solve my issue. I'd love feedback on why this doesn't work as I'd expect it to as well as more efficient/effective ways to code this. Here are the relevant code blocks:

        public void Negate()
        {
            if (Display.Length > 0)
            {
                if (Display[Display.Length - 1].Equals('-'))
                {
                    Display = Display.Substring(0, Display.Length - 1);
                }
                else if (Display[Display.Length - 1].Equals(' ') || Display[Display.Length - 1].Equals('(') ||
                    Display[Display.Length - 1].Equals('E') || Display[Display.Length - 1].Equals('^'))
                {
                    Display += '-';
                }
                else
                {
                    InvalidOperation();
                }
            }
            else
            {
                Display = "-";
            }
        }
        public void InvalidOperation()
        {
            tempDisplay = Display;
            Display = "Invalid Operation";
            Thread.Sleep(500);
            Display = tempDisplay;
        }
        public string Display
        {
            get
            {
                return _display;
            }
            set
            {
                _display = value;
                OnPropertyChanged();
            }
        }
question from:https://stackoverflow.com/questions/65601281/why-dont-delays-work-when-im-attempting-to-flash-an-error-message

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

UI will be updated only after method InvalidOperation execution is complete, so because in last line of the method you set value back to original - there are no updates in UI.

Asynchronous approach should work, because await operator will "pause" InvalidOperation method and return execution to the message loop which will update UI controls.

public async Task InvalidOperation()
{
    tempDisplay = Display;
    Display = "Invalid Operation";
        
    await Task.Delay(2000);

    Display = tempDisplay;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...