如何在wpf应用程序中最好地实现异步?

8iwquhpp  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(337)

我正在开发一个wpf应用程序,它运行sql查询并在按下时返回结果的数据网格。目前,在我尝试了解异步时,方法的结构如下所示:

public static async Task GenerateImportDataGrid( TextBox TBImportData )
{
    using( SqlConnection conn = new SqlConnection( sqlConnStr ) )
    {
        SqlTransaction transaction = conn.BeginTransaction( "InsertFromFile" );
        using( var package = new ExcelPackage( new FileInfo( TBImportData.Text ) ) )
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets.FirstOrDefault();
                int rows = worksheet.Dimension.Rows - 1;
                int columns = worksheet.Dimension.Columns - 1;
                int rowOffset = 4; //offset due to headers

                for( int i = 1; i <= rows - rowOffset; i++ ) //loop through each row
                {
                    SqlCommand insert = new SqlCommand(
                        string.Format(
                            "INSERT INTO ##COA ( mailPreparerName, barcodeEdoc, errorType, errorCode, errorDescription, errorData, jobID, mailClassEdoc, processingCategoryEdoc, mailOwnerName, scanTime) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}')",
                            worksheet.Cells[ i + rowOffset, 2 ].Value, worksheet.Cells[ i + rowOffset, 4 ].Value,
                                worksheet.Cells[ i + rowOffset, 8 ].Value, worksheet.Cells[ i + rowOffset, 9 ].Value,
                                worksheet.Cells[ i + rowOffset, 10 ].Value, worksheet.Cells[ i + rowOffset, 11 ].Value,
                                worksheet.Cells[ i + rowOffset, 13 ].Value, worksheet.Cells[ i + rowOffset, 18 ].Value,
                                worksheet.Cells[ i + rowOffset, 19 ].Value, worksheet.Cells[ i + rowOffset, 34 ].Value,
                                worksheet.Cells[ i + rowOffset, 39 ].Value ),
                            conn, transaction );
                    insert.ExecuteNonQuery();
                }
                transaction.Commit();
            }

            SqlCommand cmd = new SqlCommand( "EXEC Export", conn );
            SqlDataReader reader = await cmd.ExecuteReaderAsync();

            DataTable resultSet = new DataTable();
            await Task.Run( () => resultSet.Load( reader ) );

            DataDisplay results = new DataDisplay( resultSet ); //DataDisplay is just a window containing a DataGrid
            results.Show();
    }
}
private async void Run()
{
    ...
    PB_ProcessProgress.IsIndeterminate = true;
    await Reporting.GenerateImportDataGrid( TBImportData );
}
private void BtnView_Click( object sender, RoutedEventArgs e )
{
      ...
      Run();
}

根据所运行的查询,我的应用程序可以在30秒到20分钟之间的任何时间获取数据。我的应用程序上有一个progressbar,我真的很想在处理数据时使用它,但是我很难弄清楚如何最好地实现它 async 以及 await ,无论是在我的函数中还是在调用它的时候。
我真的很感激任何帮助!

erhoui1w

erhoui1w1#

ado.net具有 async 等价物 Commit 以及 ExecuteReaderAsync .
如果你想办法 async 您可以使用并等待:

public static async Task GenerateImportDataGrid(TextBox TBImportData)
{
    using (SqlConnection conn = new SqlConnection(sqlConnStr))
    using (SqlTransaction transaction = conn.BeginTransaction("InsertFromFile");
    {
        //bunch of inserts are executed as part of the transaction
        await transaction.CommitAsync();

        using (SqlCommand cmd = new SqlCommand("EXEC Export", conn))
        {
            SqlDataReader reader = await cmd.ExecuteReaderAsync();
        }

        DataTable resultSet = new DataTable();
        resultSet.Load(reader);

        DataDisplay results = new DataDisplay(resultSet); //DataDisplay is just a window containing a DataGrid
        results.Show();
    }
}

这样做将在异步工作发生时释放ui线程,保持应用程序的响应性。
如果你发现了 resultSet.Load(reader) 也很昂贵,这也可能会锁定你的应用程序。
由于这是cpu受限的工作,您必须通过在线程池上运行来缓解此问题:

await Task.Run(() => resultSet.Load(reader));

这也将释放ui线程。

相关问题