isx*_*ker 5 .net c# sql function
我有一个表Guid
作为主键.该表已包含很多行.此外,我有一个win service
,每行执行一些操作(可能需要从另一个数据库读取和写入数据).因此,处理一行需要花费大量时间.(平均约100秒)
我的胜利服务是这样的:
public class MyDto
{
public Guid Id { get; set; }
}
while (true){
if(time to start){
List<MyDto> rows = LoadData();
foreach(MyDto obj in rows){
Process(obj);//it takes in average about 100 sec
}
}
}
Run Code Online (Sandbox Code Playgroud)
我需要减少所有行的执行时间.由于某种原因,我决定增加我的胜利服务的失误.所以我需要每个win服务都会获得自己的行集.
我参与了我的LoadData()
乐趣:
public List<MyDto> LoadData(int winServInstanceNumber){
}
Run Code Online (Sandbox Code Playgroud)
所以我需要一个贡献函数取决于总win服务实例计数和concreate win服务实例号.
你能提供更好的东西吗?
//on .net side
obj.Id.GetHashCode()%totalWinServiceInstancesCount
Run Code Online (Sandbox Code Playgroud)
要么
--on sql side
HASHBYTES('MD5', CAST(id as varbinary(16)))%totalWinServiceInstancesCount
Run Code Online (Sandbox Code Playgroud)
看起来您所需要的只是旋转更多线程来处理数据。但要做到这一点,你需要控制你处理的内容,以免重复处理同一件事。MSMQ
例如,要获取控件,您可以使用或System.Collections.Queue
。您的服务应该负责查询数据库并将未处理的行加载到队列中。
然后,您可以调用一些静态方法ProcessBatch
。它将进入队列并旋转一个线程,并将行的 id 传递给处理器/Workers。工作人员只会处理一行。Worker可以是单独的EXE并在进程外运行。您的“ProcessBatch”应该控制处理/未处理的内容。它应该控制当前正在运行的线程数量。你不想旋转太多。
所以
Service ProcessControl Worker
| | |
|---Load Queue | |
| | | |
|<--------| | |
| | |
|-----Call When Q ----->|---Queue |
| | | |
| |<------| |
| | |
|---Load Queue |----Start------>|
| | |<---Success-----|
|<-------| | |
| |---Permanent |
|-----Call When Q ----->| Dequeue |
| | | |
| |<------| |
Run Code Online (Sandbox Code Playgroud)
这可能是典型的工作负载分割,可以加快原本缓慢的流程