【发布时间】:2021-01-19 22:48:30
【问题描述】:
我有一个 WPF 应用程序,它调用需要几分钟才能运行的 SQL Server 存储过程。此存储过程在其处理期间写入日志表。我想在存储过程运行时在网格中显示日志消息。
我有一个 while 循环,它在检查 IAsyncResult 中是否有 IsCompleted 时似乎正在工作,但在主存储过程完成之前,我的网格不会显示任何内容。如何在主存储过程运行时显示日志消息?
private void Button_Click(object sender, RoutedEventArgs e)
{
string connString = @"Data Source=MyServer;Initial Catalog=MyDatabase;Integrated Security=True; Asynchronous Processing=True";
try
{
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("dbo.RunLongProcess", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 0;
IAsyncResult result = cmd.BeginExecuteNonQuery();
while (!result.IsCompleted)
{
System.Threading.Thread.Sleep(1000);
using (SqlConnection connSteps = new SqlConnection(connString))
{
connSteps.Open();
using (SqlCommand cmdSteps = new SqlCommand("EXEC dbo.ReturnProcessSteps", connSteps))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmdSteps))
{
DataTable dt = new DataTable();
da.Fill(dt);
grdStepsTaken.ItemsSource = dt.DefaultView;
}
}
connSteps.Close();
}
}
cmd.EndExecuteNonQuery(result);
}
conn.Close();
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
【问题讨论】:
-
干净的方式:
Progress<T>。肮脏的方式:Application.DoEvents。这些有帮助吗? -
@RobJ,您需要在另一个线程中运行 ReturnProcessSteps 并根据需要更新 UI。尽可能避免 Application.DoEvents。
-
因为代码永远不会赢得美丽奖:走脏路。看起来所有的逻辑都放在了点击事件和数据库中,UI访问,计算和逻辑都混合在一起了。
-
谢谢,现在可以使用了。 Application.DoEvents 成功了。
-
@TheodorZoulias - 很多个月前,我正在开发一个 Windows 窗体应用程序,结果出现间歇性重入问题。试图找出原因是一团糟,结果
Application.DoEvents()是罪魁祸首——它不在堆栈跟踪中。太难找了。
标签: c# sql-server wpf asynchronous ado.net