0

我的 WPF 用户控件上有一个 BackgroundWorker。

        private readonly BackgroundWorker worker = new BackgroundWorker();

        public ucCustomer()
        {
          InitializeComponent();
          worker.DoWork += worker_DoWork;
          worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        }
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // run all background tasks here
            System.Threading.Thread.Sleep(10000);
        }

        private void worker_RunWorkerCompleted(object sender,  RunWorkerCompletedEventArgs e)
        {
            //update ui once worker complete his work
        }
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            worker.RunWorkerAsync();
        }

上面的代码是工作,当任务工作时 UI 是响应,但是如果我将 worker_DoWork() 更改为

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    // run all background tasks here
   Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, 
        new Action(() => {
        gridDataBind(); //A long data-mining task,using Dispatcher.Invoke() to access UI.
    }));
} 

private void gridDataBind()
{
    SnEntities sn = new SnEntities();
    var customers = from c in sn.Customer select c;
    dgCustomer.ItemsSource = customers.ToList();
}

UI 会冻结,直到任务结束。

有什么解决办法吗?谢谢。

4

3 回答 3

1

尝试像下面的代码设置 ItemsSource:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    // run all background tasks here
    e.Result = gridDataBind(); //A long data-mining task.
}

private IList<Customer> gridDataBind()
{
    SnEntities sn = new SnEntities();
    var customers = from c in sn.Customer select c;
    return customers.ToList();
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        var customers = e.Result as IList<Customer>;

        ObservableCollection<Customer> gridItemsSource = new ObservableCollection<Customer>();
        Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
                             new Action(() =>
                             {
                                 dgCustomer.ItemsSource = gridItemsSource;
                             }));

        foreach(var customer in customers)
        {
            Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
                                 new Action(() =>
                                 {
                                     gridItemsSource.Add(customer);
                                 }));
        }

    }
于 2013-10-31T04:33:07.373 回答
0

试试这个,它应该可以帮助你

Application.Current.Dispatcher.BeginInvoke(
  DispatcherPriority.Background,
  new Action(() => gridDataBind();));
于 2013-10-31T11:43:38.563 回答
0

将您的数据存储在 worker_DoWork 的 e.result 中,并在 worker_RunWorkerCompleted 更新 UI。在这种情况下,当数据来自数据库时,UI 将是免费的。

于 2013-10-31T05:01:13.923 回答