2010-11-30 58 views
2

我有一個過程分析來自一個系統的審計數據以構建另一個系統的報告數據。有一個管理程序循環每天進行分析,並在當前迭代當天調用實體特定的過程。一些實體需要不到一秒的時間來處理,而其他實體可能需要幾分鐘時間。像在t-sql中一樣連續運行,cpu利用率從未在16核心服務器上高於8%。每個實體特定的過程都不依賴於其他實體,只是當天的所有實體在第二天開始前已經完成。如何在SQL過程中並行執行子任務

我的想法是有一個CLR管理過程,並開始在自己的線程上運行一天的較長運行過程,然後一旦快速完成,Thread.Join()長時間運行的線程等待所有實體在繼續前進之前完成那一天。

下面是我嘗試的最簡單的事情,可以只爲一個工作線程工作,並調用該線程上的開始不會導致被調用的靜態方法。我已經在HelloWorld方法中設置了一個斷點,並且它從未被擊中。

我已經在控制檯應用程序中嘗試過非常類似的東西,並且它在AsyncHelloWorld的開始處的註釋掉行中的同一線程上調用它。 SQL CLR程序中的線程有什麼不同嗎?

using System.Threading; 
using Microsoft.SqlServer.Server; 

public partial class StoredProcedures 
{ 
    [SqlProcedure] 
    public static void AsyncHelloWorld() 
    { 
     // HelloWorld(SqlContext.Pipe); 

     var worker = new Thread(HelloWorld); 
     worker.Start(SqlContext.Pipe); 
     worker.Join(); 
    } 

    public static void HelloWorld(object o) 
    { 
     var pipe = o as SqlPipe; 

     if (pipe != null) 
      pipe.Send("Hello World!"); 
    } 
} 
+0

你是否有錯誤,或者什麼都沒有發生? – Nate 2010-11-30 21:20:01

+0

HelloWorld方法永遠不會被調用。 – 2010-11-30 21:51:18

回答

6

你絕對不能這樣做。 SqlPipe與你被調用的線程的上下文非常緊密相關。雖然技術上可以從SQLCRL啓動線程,但這些線程必須與原始線程的調用者進行所有交互。但即使如此,在SQL託管環境中啓動CLR線程也是一個壞主意(我不會詳細說明爲什麼)。

相反,將您的邏輯分成可以並行調用的過程,並從客戶端並行調用這些過程。您可以使用Asynchronous procedure execution作爲以異步方式啓動的調度過程模式,並且基於隊列的激活已通過MAX_QUEUE_READERS設置內置了對並行性的支持。

但很可能您的過程不需要顯式並行性。 T-SQL加載比可以受益於明確的用戶控制並行性非常少見,不值得一提(更不用說拉動並行任務中的事務語義超越單純的凡人)。 T-SQL可以利用內部語句並行性來並行處理數據,所以從不需要顯式並行。

所以你最好解釋一下你是什麼真的試圖解決,也許我們可以幫助。