WPF背景调用DoWork事件的调用方法

时间:2013-10-31 04:18:06

标签: wpf

我的WPF UserControl上有一个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冻结,直到任务结束。

有什么解决方案吗? 谢谢你。

3 个答案:

答案 0 :(得分: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);
                                 }));
        }

    }

答案 1 :(得分:0)

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

答案 2 :(得分:0)

试试这个,它可以帮到你

Application.Current.Dispatcher.BeginInvoke(
  DispatcherPriority.Background,
  new Action(() => gridDataBind();));