【发布时间】:2011-02-03 09:59:07
【问题描述】:
我制作了一个小实用程序来测试 PC 是否有可能连接到某个 Oracle 数据库。
为了保持 UI 响应并查看进度步骤,我将 DB 代码放在后台线程中。令我惊讶的是,UI 仍然挂起(但没有那么多)。
这个app真的没什么大不了,但是我觉得这个案例总体来说很有趣,线程中的DB代码挂了UI线程!
private void bgwDataAccess_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bgw = sender as BackgroundWorker;
try
{
bgw.ReportProgress(0, "Starting...\r\n");
bgw.ReportProgress(0, "Active ConnectionString:\r\n");
bgw.ReportProgress(0, Settings.Default.ConnctionString + "\r\n\r\n");
OracleConnection con = new OracleConnection(Settings.Default.ConnctionString);
OracleCommand cmd = new OracleCommand("SELECT Count(*) FROM MYTABLE", con);
bgw.ReportProgress(0, "Opening db...\r\n");
con.Open();
bgw.ReportProgress(0, "Opened.\r\n\r\n");
bgw.ReportProgress(0, "Executing SQL-query...\r\n");
Object result = cmd.ExecuteScalar();
bgw.ReportProgress(0, String.Format("Result: {0}\r\n\r\n", result.ToString()));
con.Close();
}
catch (Exception)
{
throw;
}
}
private void bgwDataAccess_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
txtResult.Text += e.UserState;
}
【问题讨论】:
-
小提示,没有解决你的问题,去掉catch,在finally中无论如何都要使用try-finally关闭连接。您应该在 try 块之前声明(但不打开)连接,以便能够在 finally 中使用 con 对象。
-
是的,你完全正确!
-
你能定义/描述“挂起 UI 线程”吗?这有多严重?
-
为什么你在做一个BackgroundWorker bgw = sender as BackgroundWorker;和 bgw.ReportProgress(0, "开始...\r\n");?您可以直接调用 bgwDataAccess.ReportProgress() 对吗?也使用 Using() 而不是显式关闭/处理连接
-
您确定BackgroundWorker设置为支持报告进度(WorkerReportsProgress)?
标签: c# database multithreading oracle user-interface