C# WPF App-异步等待方法调用未呈现进度消息

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

我正在构建一个简单的WPF应用程序,并希望展示label字段中的进度。但我只是第一次收到进展信息,但没有收到后续执行的进展信息

在随后的按钮点击中,我只看到消息“queryexecutesuccessfully”

我不知道我哪里出错了。。我正在尝试打印进度消息。请说明我在哪里犯了错误,哪些代码语句需要移动或重构

  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));
}