从 SQL Server 返回进程信息
本文关键字:进程 信息 返回 Server SQL | 更新日期: 2023-09-27 18:10:48
全部,我有一些复杂的C#代码(Windows Forms(,这些代码大量嵌入了对SQL Server的调用(假定的服务器版本为2008 R2或更高版本(。就目前而言。代码是串行的,我被要求多线程它。这种多线程过程现在专门与代码的昂贵部分相关联,即代码执行"繁重工作"的地方。大部分工作都是使用 SQL Server 查询完成的。
我即将开始对处理对SQL Server调用的主处理器进行多线程处理。我想通过"SQL线程"的进度向用户提供信息,因为SQL过程可能很长。我想知道我的方法听起来是否合理,或者是否有更好的方法。我的方法如下:(注意:下面的代码只是我在尝试使用实际代码之前构建的一个小示例(
A. 从主窗体上的按钮单击事件启动BackgroundWorker
线程。
Bgw = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
Bgw.DoWork += new DoWorkEventHandler(Bgw_DoWork);
Bgw.ProgressChanged += new ProgressChangedEventHandler(Bgw_ProgressChanged);
Bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Bgw_RunWorkerCompleted);
Bgw.RunWorkerAsync();
二.从Bgw_DoWork
事件中,我启动了位于类 HeavyWork
中的 SQL 方法。
void Bgw_DoWorkSQL(object sender, DoWorkEventArgs e)
{
Hw = new HeavyWork(this, ref Bgw, ref e);
Hw.SQLProc();
return;
}
C. 从BackgroundWorker
(这次不是BackgroundWorker
(从Hw.SQLProc
内启动另一个后台线程,以便捕获 SQL 查询的进度并促进 SQL Server 查询的取消。
// Globals.
private bool bConnOpen = false;
private SqlConnection conn = null;
private Form _MainForm;
private BackgroundWorker _Bgw;
private DoWorkEventArgs _e;
public void SQLProc()
{
bool bConnOpen = false;
const string strSqlConnMaster = "Data Source = localhost; Initial Catalog = RMH1006DHFinal; Integrated Security " + "= True; MultipleActiveResultSets = True; Connection Timeout = 0";
const string strSQL = "DBCC CHECKDB"; // Expensive SQL Non-Query.
try
{
// Create new SQL connection.
conn = new SqlConnection(strSqlConnMaster);
// Execute the SQL Non-Query.
conn.Open();
bConnOpen = true;
// Start another thread to get user information and for cancellation purposes.
Thread SQLThread = new Thread(myMethod); // This is not working.
SQLThread.IsBackground = true;
SQLThread.Start();
// Now run big query.
_Bgw.ReportProgress(0, String.Format("Processing SQL Command '{0}'...", strSQL));
ExecNonQuery(conn, strSQL);
conn.Close();
bConnOpen = false;
return;
}
catch (Exception)
{
throw;
}
finally
{
if (bConnOpen)
conn.Close();
}
}
总之,我想在单独的BackgroundWorker
上启动昂贵的SQL查询。在BackgroundWorker
线程上调用的方法(使用SQL连接发送的一些查询,称之为SqlConnection conn
(,启动另一个Thread
,该使用单独的SqlConnection connNew
进入另一个mathod,该重新修订有关conn
上主要进程的信息。
我想知道这是一种有效的方法吗?另外,如果可以从BackGroundWorker
启动新的Thread
,因为上面的代码没有在新线程上启动myMethod
方法?
提前谢谢大家。
如果我理解正确,您想指示进度,但不能,因为ExecNonQuery
块。
作为良好做法,如果您的数据库调用可能需要超过一秒钟的时间,我不会为此使用 BackgroundWorker ,因为 BW 使用线程池线程。相反,我会使用一个新的线程,或者,如果你使用的是 .NET 4.0,我会使用一个带有 TaskCreationOptions.LongRunning
的任务。
报告:您的数据库调用块,因此您可以显示的唯一进度是正在运行或已完成,因此我会显示某种选框进度指示器。我会使用 Timer 从 UI 线程控制它 - 你真的不想仅仅为了做动画而启动线程,无论如何你都想在 UI 线程上。
如果你想从后台线程中剥离一个新的线程,那很好。 但是,正如您所说,设置方式在其当前状态下不起作用。
Thread SQLThread = new Thread(myMethod); // This is not working.
。应该变成...
Thread SQLThread = new Thread(new ThreadStart(myMethod));
...
。或者简单地...
Thread SQLThread = new Thread(()=>myMethod());