C#WPF更新UI的测试问题

我用MVVM模式更新界面,增加延时后界面无反应。单次执行后可以更新界面。不知道问题出在哪里?

img

界面设置如下:

 <TextBox x:Name="txtbloc" Grid.Row="0" Width="200" Height="100" Text="{Binding m_person.Name, Mode=OneWay}" Background="#FF9FAF40"></TextBox>
        <TextBox Width="200" Height="100" Text="{Binding m_person.Age, Mode=TwoWay ,NotifyOnSourceUpdated=True}" Margin="31,180,569,205" />
        <Button x:Name="UpdateBtn" Content="更新" Width="300" Command="{Binding ChangeCommand}"  FontSize="24"  Margin="230,34,270,385" />

对应的代码如下:

 public class ViewModel : MVVMObject
    {
        public ICommand ChangeCommand { get; set; }
        public Person m_person { get; set; } = new Person{ Name="GG",Age=4};
        public ViewModel()
        {

            ChangeCommand = new CommandBase(()=>
            {
                Hellow();
            });

        }
        private void Hellow()
        {
          while (true) {//增加无限循环后无法正常更新界面
                Task.Delay(1000).GetAwaiter().GetResult();
                Random rnd = new Random();
                m_person.Age = rnd.Next();
                m_person.Name = "ffff" + rnd.Next();
            }
        }
        
    }

private async void Hellow()
{
    while (true)
    {
        await Task.Delay(1000); // 使用异步等待确保不阻塞主线程

        // 在 UI 线程上执行更新界面的操作
        Application.Current.Dispatcher.Invoke(() =>
        {
            Random rnd = new Random();
            m_person.Age = rnd.Next();
            m_person.Name = "ffff" + rnd.Next();
        });
    }
}

【以下回答由 GPT 生成】

问题出在无限循环中的Hellow()方法内部。由于无限循环是同步执行的,会阻塞UI线程,导致界面无法更新。解决这个问题的一种方法是将Hellow()方法改为异步方法,并使用await Task.Delay代替同步延迟。以下是修改后的代码示例:

private async void Hellow()
{
    while (true) 
    {
        await Task.Delay(1000);
        Random rnd = new Random();
        m_person.Age = rnd.Next();
        m_person.Name = "ffff" + rnd.Next();
    }
}

修改后的Hellow()方法使用async关键字声明为异步方法,内部使用await Task.Delay(1000)替代Task.Delay(1000).GetAwaiter().GetResult(),实现异步延时。这样可以防止阻塞UI线程,使界面能够正常更新。

另外,为了确保界面更新的线程安全,需要在ViewModel的属性属性上使用InvokePropertyChanged方法来通知UI进行更新。以下是修改后的ViewModel代码示例:

public class ViewModel : MVVMObject
{
    public ICommand ChangeCommand { get; set; }
    private Person _person;
    public Person m_person 
    {
        get { return _person; }
        set { 
            _person = value; 
            InvokePropertyChanged("m_person");
        }
    } 

    public ViewModel()
    {
        ChangeCommand = new CommandBase(()=>
        {
            Hellow();
        });
    }
    private async void Hellow()
    {
        while (true) 
        {
            await Task.Delay(1000);
            Random rnd = new Random();
            m_person.Age = rnd.Next();
            m_person.Name = "ffff" + rnd.Next();
        }
    }
}

m_person属性的set方法内部,添加了InvokePropertyChanged("m_person")来通知UI刷新。

这样修改之后,界面就能在增加了延时和循环后进行正常更新了。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^