【发布时间】:2020-10-24 04:50:34
【问题描述】:
我正在开发一个运行 SQL 查询并在按下时返回结果的数据网格的 WPF 应用程序。 目前,我尝试找出异步方法的结构如下:
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 分钟之间的任何时间。我的应用程序上有一个进度条,我真的很想在处理数字时使用它,但是我很难弄清楚如何最好地实现async 和await,无论是在我的函数中还是在它被调用的时候。
非常感谢任何帮助!
【问题讨论】:
-
将
cmd.ExecuteReader()替换为await cmd.ExecuteReaderAsyn()。将您的方法声明为async Task而不是void,并在async voidClick 处理程序方法中调用(并等待)它。 -
不是你问的,但我建议你看看 dapper。它在 ado 上提供了扩展方法,可以更轻松地从数据表和数据集移动到 dto 列表。
-
@Clemens 感谢您的回复!我尝试实施您的建议以及 Johnathan Barclay 对
await Task.Run(() => resultSet.Load(reader));的建议,但应用程序仍然锁定 :( 你能检查我的新编辑并再次帮助我吗? -
@sirius_pain 什么是插入物?你能添加那个代码吗?
-
您仍在使用一些阻塞调用
ExecuteNonQuery和Commit。此外,您应该参数化您的 SQL 语句,而不是使用易于 SQL 注入的string.Join。
标签: c# sql wpf asynchronous