我这堂课,它运作良好
public partial class Home : UserControl
{
public ObservableCollection<Activity> DataGridRows { get; set; }// = new ObservableCollection<Activity>();
public Home()
{
InitializeComponent();
DataContext = this;
this.Init();
}
private void Init()
{
DataGridRows = new ObservableCollection<Activity>();
refreshGrid(null, null);
}
private void refreshGrid(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
startRefresh(); //<-- very long operation!
}));
}
}
我的问题是,在调用startRefresh()时,整个程序被冻结,我无法点击其他按钮或执行其他操作,直到startRefresh完成。但是我想在后台运行它。 请注意,我不能将Task对象与TaskScheduler.FromCurrentSynchronizationContext()方法一起使用,因为startRefresh对DataGridRows执行编辑操作,我得到以下异常:
System.NotSupportedException : This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
答案 0 :(得分:1)
您需要移动重要数据从UI线程获取和处理。数据准备就绪后,从UI线程更新UI。如果您使用的是.NET 4.0或更高版本,Task Parallel Library可以使这种操作变得更容易。
注意:我假设startRefresh()
既获取数据又更新UI。如果数据检索和UI更新采用不同的方法,您将更容易自己。
有关详细信息,请参阅此答案: Avoiding the window (WPF) to freeze while using TPL
答案 1 :(得分:0)
我认为你可以使用等待的委托命令
public ICommand MyCommand { get; set; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
MyCommand = new AwaitableDelegateCommand(refreshGrid);
}
private async Task refreshGrid()
{
await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
Thread.Sleep(10000);
}));
}
您可以查看http://jake.ginnivan.net/awaitable-delegatecommand/等待委托命令