加载

时间:2016-02-26 12:05:58

标签: c# wpf multithreading

-->

我这堂课,它运作良好

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.

2 个答案:

答案 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/等待委托命令

相关问题
最新问题