C# WPF App-异步等待方法调用未呈现进度消息
我正在构建一个简单的WPF应用程序,并希望展示label字段中的进度。但我只是第一次收到进展信息,但没有收到后续执行的进展信息 在随后的按钮点击中,我只看到消息“queryexecutesuccessfully” 我不知道我哪里出错了。。我正在尝试打印进度消息。请说明我在哪里犯了错误,哪些代码语句需要移动或重构C# WPF App-异步等待方法调用未呈现进度消息,c#,wpf,async-await,C#,Wpf,Async Await,我正在构建一个简单的WPF应用程序,并希望展示label字段中的进度。但我只是第一次收到进展信息,但没有收到后续执行的进展信息 在随后的按钮点击中,我只看到消息“queryexecutesuccessfully” 我不知道我哪里出错了。。我正在尝试打印进度消息。请说明我在哪里犯了错误,哪些代码语句需要移动或重构 private async void btnRunQuery_Click(object sender, RoutedEventArgs e) { if (tx
private async void btnRunQuery_Click(object sender, RoutedEventArgs e)
{
if (txtQueries.Text.Length > 0)
{
lblMsg.Content = "Query execution in progress.... Please wait ....";
lblMsg.Foreground = new SolidColorBrush(Colors.Orange);
}
await PopulateQueryExecutionResult();
}
private async Task PopulateQueryExecutionResult()
{
ResultList.ItemsSource = null; //Clear the control hierarchy before binding.
if (txtQueries.Text.Length > 0)
{
lblMsg.Content = "Query execution in progress.... Please wait ....";
lblMsg.Foreground = new SolidColorBrush(Colors.Orange);
btnExport.IsEnabled = true;
DataTable dt = new DataTable();
SqlConnection sqlconn = new SqlConnection(ConstructConnectionString(cmbEnv.SelectedValue.ToString(), cmbDbs.SelectedValue.ToString()));
string commandtext = "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;"; //Make Dirty read to prevent locking
commandtext += txtQueries.Text;
try
{
SqlDataAdapter dp = new SqlDataAdapter(commandtext, sqlconn);
await sqlconn.OpenAsync();
dp.SelectCommand.CommandTimeout = 0;
DataSet ds = new DataSet();
dp.Fill(ds, "QueryData");
dt = ds.Tables["QueryData"];
ResultList.ItemsSource = dt.DefaultView;
sqlconn.Close();
lblMsg.Content = "Query executed successfully";
lblMsg.Foreground = new SolidColorBrush(Colors.Black);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Exception in the Query ::--> {0} \n\n StackTrace ::--> {1} ", ex.Message, ex.StackTrace));
}
}
else
{
MessageBox.Show("At least write some query first!!!", "Query Execution Tool");
}
}
我认为问题在于DataAdapter的
Fill()
方法被阻塞,这可能意味着连续尝试从未完成,但“查询执行成功”显示错误。这可能会给你一个误报指标,它一定是第一次完成的
我建议在执行Fill()
方法后更改UI的状态,而不是在调用该方法后更改,因为它是一种阻塞方法,所以我会这样做:
try
{
await sqlconn.OpenAsync();
using (SqlDataAdapter dp = new SqlDataAdapter(commandtext, sqlconn))
{
dp.SelectCommand.CommandTimeout = 0;
await Task.Run(() => (Action)delegate {
dp.Fill(dt);
ResultList.ItemsSource = dt.DefaultView;
lblMsg.Content = "Query executed successfully";
lblMsg.Foreground = new SolidColorBrush(Colors.Black);
sqlconn.Close();
});
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Exception in the Query ::--> {0} \n\n StackTrace ::--> {1} ", ex.Message, ex.StackTrace));
}
您可能会发现“queryexecutesuccessfully”不再出现,如果是这种情况,那么我建议您的SQL中存在错误,而不是代码中的错误
科达
在随后的按钮点击中,我只看到消息“queryexecutesuccessfully”
这可能是因为OpenAsync()
方法返回fast,以便您能够实际看到“正在执行查询…”消息。这不应该是个问题。如果希望代码运行较慢,可以按照注释中的建议引入延迟:
try
{
SqlDataAdapter dp = new SqlDataAdapter(commandtext, sqlconn);
await sqlconn.OpenAsync();
await Task.Delay(3000); //<--
dp.SelectCommand.CommandTimeout = 0;
DataSet ds = new DataSet();
dp.Fill(ds, "QueryData");
dt = ds.Tables["QueryData"];
ResultList.ItemsSource = dt.DefaultView;
sqlconn.Close();
lblMsg.Content = "Query executed successfully";
lblMsg.Foreground = new SolidColorBrush(Colors.Black);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Exception in the Query ::--> {0} \n\n StackTrace ::--> {1} ", ex.Message, ex.StackTrace));
}
您需要使用Progress类。查看是否有可能代码执行得太快,以至于您看不到其他消息?您可以在设置最终消息之前设置延迟,例如5秒。通过调用
wait Task.Delay(5000)
@Karan您的想法是以某种方式可视化打开数据库连接的进度。现在你应该问问自己这是否真的有必要。我建议延迟只是为了验证消息是否真的显示出来。对于生产代码,我从来没有建议过这样的事情!你能建议用等待和填充法吗。。这就是UI主线程被阻塞的地方…这与我一小时前回答的答案几乎相同,但我没有解释就被否决了?
try
{
SqlDataAdapter dp = new SqlDataAdapter(commandtext, sqlconn);
await sqlconn.OpenAsync();
dp.SelectCommand.CommandTimeout = 0;
await Task.Run(() =>
{
DataSet ds = new DataSet();
dp.Fill(ds, "QueryData");
dt = ds.Tables["QueryData"];
});
ResultList.ItemsSource = dt.DefaultView;
sqlconn.Close();
lblMsg.Content = "Query executed successfully";
lblMsg.Foreground = new SolidColorBrush(Colors.Black);
}
catch (Exception ex)
{
MessageBox.Show(string.Format("Exception in the Query ::--> {0} \n\n StackTrace ::--> {1} ", ex.Message, ex.StackTrace));
}