Den*_*len 2 sql multithreading sqlclr
我有一个流程来分析来自一个系统的审计数据,以构建另一个系统的报告数据.有一个管理程序循环每天进行分析,并在当前迭代日调用实体特定程序.有些实体需要不到一秒的时间来处理,而其他实体可能需要几分钟.像在t-sql中一样串行运行,16核服务器上的cpu利用率从未达到8%以上.每个实体特定程序不依赖于其他程序,只是当天的所有实体在第二天开始之前完成.
我的想法是拥有一个CLR管理程序,并在他们自己的线程上运行当天运行时间较长的程序,然后一旦快速完成,Thread.Join()长时间运行的线程等待所有实体完成前一天继续下一个.
下面是我的尝试作为最简单的事情,只适用于一个工作线程,并在该线程上调用Start不会导致调用静态方法.我在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!");
}
}
Run Code Online (Sandbox Code Playgroud)
你绝对不能那样做.SqlPipe与您调用的线程的上下文密切相关.虽然从技术上讲,您可以从SQLCRL启动线程,但这些线程必须与原始线程中的调用者进行所有交互.但即便如此,在SQL托管环境中启动CLR线程也是一个非常糟糕的主意(我不会详细说明原因).
相反,将您的逻辑分离为可以并行调用的过程,并从客户端并行调用这些过程.您可以使用异步过程执行作为调度过程的模式以异步方式启动,并且基于队列的激活通过MAX_QUEUE_READERS设置内置支持并行性.
但很可能您的程序不需要显式并行.可以从显式用户控制的并行性中受益的T-SQL负载非常罕见,不值得一提(更不用说在并行任务中提取事务语义不仅仅是凡人).T-SQL可以利用内部语句并行性来并行处理数据,因此不需要显式并行.
所以你能更好地解释你真正想要解决的问题,也许我们可以提供帮助.
| 归档时间: |
|
| 查看次数: |
2871 次 |
| 最近记录: |