在我要等待的方法上获取无法等待的空隙 [英] Getting a Cannot await void, on a method that I have want to await on

查看:162
本文介绍了在我要等待的方法上获取无法等待的空隙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm on a team writing a WPF app. We have to make it so that when a user hides/shows different columns that it will reflect that in a ReportViewer control on one of the views. In testing we've found that it takes a long time to add the data to the ReportViewer's data sources; sometimes on the order of several seconds to possibly a minute. Too long I think for the users. So I'm trying to use C#'s async and await. However, when I applied await to the line that is the process hog and then compile it, I get an error from the C# compiler, "Cannot await 'void'". In this case, I cannot change what the .NET framework returns, its void. So how do I handle this situation? Here's the code:

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<Grievance>;
    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:

For methods that are inherently synchronous, you need to wrap them in your own Task so you can await it. In your case, I would just use Task.Run:

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

还有其他生成任务的方法,但这可能是最简单的方法.如果此操作更新了UI组件,则可能会引发异常,因为这些操作必须在UI线程上进行.在这种情况下,请尝试使与UI相关的部分远离长时间运行的部分,而仅将较长的部分包装在Task中.

There are other ways to generate a task, but this one is probably the easiest. If this updates a UI component, it will likely throw an exception because those operations must occur on the UI thread. In this case, try to get the UI related piece away from the long-running part and only wrap the long part in the Task.

这篇关于在我要等待的方法上获取无法等待的空隙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆