gpt4 book ai didi

c# - 从工作线程更新 View 模型会引发跨线程问题

转载 作者:太空宇宙 更新时间:2023-11-03 21:12:36 25 4
gpt4 key购买 nike

最近,我一直在测试实现 INotifyPropertyChanged 的类型的绑定(bind),并从抛出跨线程问题的工作线程更新属性。

这里是示例代码:

public class MyViewModel : INotifyPropertyChanged
{
private string _name;

public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged("Name");
}
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{

PropertyChangedEventHandler hanlder = PropertyChanged;
if(hanlder != null)
hanlder(this, new PropertyChangedEventArgs(propertyName));

}
}

上面的 View 模型已经与窗口窗体中的标签文本绑定(bind),并从工作线程更新标签值。

从工作线程更新 label1 文本会导致跨线程问题:

public partial class MainForm : Form
{
private MyViewModel _myViewModel = new MyViewModel();
public MainForm()
{
InitializeComponent();
Btn1.Click += Btn1_Click;
label1.DataBindings.Add("Text", _myViewModel, "Name");

}

private void Btn1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
_myViewModel.Name = "Updating from worker thread!"; It causes cross thread issue
});
}
}

到目前为止,我可以相信这是由于从工作线程更新 UI。是否有任何解决方法可以在不更改按钮单击方法的情况下使其线程安全,即可能在 View 模型中使线程安全。

最佳答案

获取 UI 的 SynchronizationContext(例如,在应用程序启动时从 UI 线程使用 SynchronizationContext.Current),并将其存储在某处的某个静态变量中(我'我们将其命名为 uiSynchronizationContext)。

然后在您的 OnPropertyChanged 上执行如下操作:

protected virtual void OnPropertyChanged(string propertyName)
{
uiSynchronizationContext.Post(
o => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))
,null
);
}

或者你可以使用Send而不是Post,如果你希望同步操作(与启动发送/发布操作的线程同步,它总是“同步”在 UI 线程上)

我特别不喜欢在多线程时进行直接数据绑定(bind)(我更喜欢从一些具有更改的图形对象的 UI 线程上使用计时器进行轮询),但这应该可以解决问题。

我承认我还没有测试过

关于c# - 从工作线程更新 View 模型会引发跨线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36688026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com