在我想要等待的方法上获取a无法等待无效

我正在写一个WPF应用程序的团队。 我们必须这样做,以便当用户隐藏/显示不同的列时,它将反映在其中一个视图的ReportViewer控件中。 在测试中,我们发现将数据添加到ReportViewer的数据源需要很长时间; 有时大约几秒到一分钟。 我想为用户太久了。 所以我正在尝试使用C#的异步并等待。 但是,当我将await应用于进程hog然后编译它时,我从C#编译器得到一个错误,“无法等待’void’”。 在这种情况下,我无法改变.NET框架返回的内容,它的空白。 那么我该如何处理这种情况呢? 这是代码:

private async Task GenerateReportAsync() { DataSet ds = new DataSet(); DataTable dt = new DataTable(); dt.Clear(); int iCols = 0; //Get the column names if (Columns.Count == 0) //Make sure it isn't populated twice { foreach (DataGridColumn col in dataGrid.Columns) { if (col.Visibility == Visibility.Visible) { Columns.Add(col.Header.ToString()); //Get the column heading iCols++; } } } //Create a DataTable from the rows var itemsSource = dataGrid.ItemsSource as IEnumerable; if (this.rptViewer != null) { rptViewer.Reset(); } rptViewer.LocalReport.DataSources.Clear(); if (m_rdl != null) { m_rdl.Dispose(); } Columns = GetFieldOrder(); m_rdl = CoreUtils.GenerateRdl(Columns, Columns); rptViewer.LocalReport.LoadReportDefinition(m_rdl); //the next line is what takes a long time await rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", CoreUtils.ToDataTable(itemsSource))); rptViewer.RefreshReport(); } 

对于本质上同步的方法,您需要将它们包装在您自己的Task以便您可以等待它。 在你的情况下,我只会使用Task.Run

 await Task.Run(() => { rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", CoreUtils.ToDataTable(itemsSource))); }); 

还有其他方法可以生成任务,但这可能是最简单的方法。 如果这更新了UI组件,它可能会抛出exception,因为这些操作必须在UI线程上发生。 在这种情况下,尝试将与UI相关的部分远离长时间运行的部分,并仅将长部分包装在Task

我几乎可以肯定整行不是慢线, CoreUtils.ToDataTable(itemsSource)更有可能是缓慢的部分,这是需要改进的部分。

你没有包含ToDataTable的源ToDataTable所以我不能确定最好的方法是什么,第一个也是最好的选择是编写一个新版本的函数,在内部利用异步调用来创建一个允许你的函数等待它。

 var data = await CoreUtils.ToDataTableAsync(itemsSource) rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", data)); 

第二Task.Run较低的选项是使用Task.Run在后台线程上执行缓慢的部分,然后在UI线程上根据需要设置数据源。

 var data = await Task.Run(() => CoreUtils.ToDataTable(itemsSource)); rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", data));