0

我已经查看了几个与动态 UI 相关的问题,但我仍然不明白我缺少什么。此外,我已经关注了有关如何使用任务的教程,但我的理解仍然有限。这是我想要实现的目标:

我的应用程序正在幕后做一些工作,但我希望我的 UI 能够响应。我尝试了以下方法(参见代码),但 UI 在调用调度程序之前不会开始更新。我希望 UI 状态为:

  1. 创建... - 单击 CreatePivotTableButton
  2. 建立连接... -- 在调用 provider.GetReportData 方法之前
  3. 连接成功或连接失败取决于结果
  4. 完毕。

     <!-- language: lang-cs -->
     private void CreatePivotTableButton(object sender, RoutedEventArgs e)
    {
    
        this.StatusToBeDisplayed.Content = "Creating...";
        this.DescriptionLabel.IsEnabled = false;
        this.TextBlockBorder.IsEnabled = true; 
    
        List<CombinedData> items = (List<CombinedData>)CustomerComboBox.ItemsSource;
        List<int> selectedItems = new List<int>();
        foreach (CombinedData item in items)
        {
            if (item.IsSelected)
            {
                selectedItems.Add(item.ReferenceId);
            }
        }
    
        PCTProvider provider = new PCTProvider();
        ExportToExcel export = new ExportToExcel();
    
        ExcelAutomation excelAutomation = new ExcelAutomation();
    
        this.ResultTextBlock.Text = "Establishing Connection";
        DataTable generateReportDataTable = provider.GetReportData(selectedItems);
        Excel.Workbook workbook = export.ExportDataTableToExcel(generateReportDataTable);
        Task updateTask = Task.Factory.StartNew(() =>
        {
            Dispatcher.Invoke(new Action(() => excelAutomation.CreatePivotTable(workbook)));
        }).ContinueWith(result =>
        {
            Dispatcher.Invoke(new Action(() => this.StatusToBeDisplayed.Content = "Done!"));
            Dispatcher.Invoke(new Action(() => OriginalStatus()));
        }, TaskScheduler.FromCurrentSynchronizationContext());
    
    }
    

我非常感谢您的时间和帮助。

4

1 回答 1

0

我认为您不需要ContinueWith和/或可能不需要TaskScheduler 通过在任务中完成工作,您允许 UI 线程响应消息泵。您可能希望将更多的工作CreatePivotTableButton转移到任务中。

试试这个:

private void CreatePivotTableButton(object sender, RoutedEventArgs e)
{

    this.StatusToBeDisplayed.Content = "Creating...";
    this.DescriptionLabel.IsEnabled = false;
    this.TextBlockBorder.IsEnabled = true; 
    // move the rest of the code into your Task to perform the work off the UI thread
    Task updateTask = Task.Factory.StartNew(() =>
    {
        List<CombinedData> items = (List<CombinedData>)CustomerComboBox.ItemsSource;
        List<int> selectedItems = new List<int>();
        foreach (CombinedData item in items)
        {
            if (item.IsSelected)
            {
                selectedItems.Add(item.ReferenceId);
            }
        }

        PCTProvider provider = new PCTProvider();
        ExportToExcel export = new ExportToExcel();

        ExcelAutomation excelAutomation = new ExcelAutomation();

        Dispatcher.Invoke(new Action(() => this.ResultTextBlock.Text = "Establishing Connection"));
        DataTable generateReportDataTable = provider.GetReportData(selectedItems);
        Excel.Workbook workbook = export.ExportDataTableToExcel(generateReportDataTable);

        excelAutomation.CreatePivotTable(workbook);
        Dispatcher.Invoke(new Action(() => this.StatusToBeDisplayed.Content = "Done!"));
        Dispatcher.Invoke(new Action(() => OriginalStatus()));
    });
}
于 2014-03-26T00:08:49.183 回答