Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从SQL Server返回进程信息_C#_Sql_Multithreading - Fatal编程技术网

C# 从SQL Server返回进程信息

C# 从SQL Server返回进程信息,c#,sql,multithreading,C#,Sql,Multithreading,总之,我有一些复杂的C#代码(Windows窗体),其中大量嵌入了对SQL Server的调用(2008 R2或更高版本是假定的服务器版本)。就目前而言。代码是串行的,我被要求对其进行多线程处理。这个多线程处理过程现在特别与代码的昂贵部分相关,即代码执行“繁重”操作的地方。大部分工作是通过SQL Server查询完成的 我即将开始多线程处理主处理器,它处理对SQL Server的调用。我想通过“SQL线程”的进度向用户提供信息,因为SQL过程可能非常长。我想知道我的方法听起来是否合理,或者是否有

总之,我有一些复杂的C#代码(Windows窗体),其中大量嵌入了对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();  
B.从
Bgw_DoWork
事件中,我启动了我的SQL方法,它位于类
HeavyWork

void Bgw_DoWorkSQL(object sender, DoWorkEventArgs e)
{
    Hw = new HeavyWork(this, ref Bgw, ref e);
    Hw.SQLProc();
    return;
} 
C.从
Hw.SQLProc
内的
BackgroundWorker
(这次不是
BackgroundWorker
)启动另一个后台线程,以捕获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
),启动另一个
线程
,该线程使用单独的
SqlConnection connNew
进入另一种方法,该方法在
conn
上检索有关主进程的信息

我想知道这样做有效吗?另外,如果可以从
BackGroundWorker
启动新的
线程
s,因为上面的代码没有在新线程上启动
myMethod
方法


提前感谢大家。

如果您想从背景线程中衍生出一个新线程,那很好。但是,正如您所说的,如何设置它在当前状态下不起作用

Thread SQLThread = new Thread(myMethod); // This is not working. 
…应该变成

Thread SQLThread = new Thread(new ThreadStart(myMethod));
...
……或者干脆

Thread SQLThread = new Thread(()=>myMethod());

如果我理解正确,您希望指示进度,但不能,因为
execonquery
阻塞

作为一种良好的实践,如果db调用可能需要一秒钟以上的时间,我不会为此使用BackgroundWorker,因为BW使用线程池线程。相反,我会使用一个新线程,或者,如果您在.NET4.0上,则使用带有
TaskCreationOptions.LongRunning
的任务


回到您的进度报告:您的db调用阻塞,因此您可以显示的唯一进度是正在运行或已完成,因此我将显示某种字幕进度指示器。我会使用计时器从UI线程控制这一点-你不想仅仅为了制作动画而启动线程,而且你还是想进入UI线程。

嗨,乔治,谢谢你的评论。我现在想知道为什么
SQLThread.Start()在这种情况下不起作用?在第二个例子中,
Thread()=>myMethod())
委托被声明并立即分离。第一个是ThreadStart,它只是简单地声明它,并且它仍然需要一个Thread.StartGeorge,谢谢您的帮助。然而,尽管上面的建议很有帮助,但它们并没有回答我的问题——事实上,我的代码做的是正确的,但优先级处于其默认级别——这意味着线程在主SQL查询启动之前不会被取消,这就是我没有看到它的原因。再次感谢。你好,尼克,谢谢你的回复。我的想法是使用连接a在一个单独的线程a上启动昂贵的SQL查询,但也启动另一个线程B,该线程B使用连接B从SQL Server获取进度完成值,使用会话id={0}的sys.dm_exec_请求中的
选择完成百分比
此处的会话id可以使用连接A从线程B确定。这就提出了一个问题;能否同时使用两个不同的连接访问SQL Server?另外,我不确定我是否理解你关于BGW线程的说法——这就是重点,不是吗?@Killercam:docs说,这只适用于有限的一组SQL语句。另外,在服务器上执行SQL语句时,无法报告其进度。BGW是在.NET2.0中引入的-我现在在大多数情况下都会避免使用它,特别是当您使用TPL时。我知道它的使用是有限的。谢谢你是说现在不应该使用
BackgroundWorker
?我有Joesph Albahari的书C#4.0,简而言之,在使用
BackgroundWorker
执行长时间运行的任务时,他没有说明任何此类问题。它不仅仅是基于事件的异步模式的通用实现。此外,请检查SBGW是否可以并且应该用于此类目的。