我当前的网站设置为在第一次有人登录应用时为某些人留言。剩下的消息数可以是1000到10000之间的任意值,每个消息都是查询,以及事务语句中的所有查询。
是的,我知道这看起来很糟糕,这不是我的问题。
目前,当用户登录时,服务器必须在用户实际执行任何操作之前完成所有查询。我的意思是,用户查看登录屏幕,直到超时启动并重置页面。最近我们已经等了30分钟(!)
我想将此过程放在一个线程上,以便用户可以登录网站,执行他/她需要的任何活动,并查看/删除他们的消息,同时不受消息传递者的阻碍。
我的问题是,是否只是旋转一个新线程来处理这个过程来解决问题(即允许用户在传递者留下消息时工作)?旋转线程是否会影响同一服务器上的其他Web应用程序?
编辑基于KM的评论
简化架构:
任务表:
TaskID StartDate EndDate PercentComplete TSK1 4/17/09 5/17/09 60 TSK2 3/19/09 3/29/09 80 TSK3 1/1/08 2/9/09 100
作业表:
TaskID ResourceID TSK1 111 TSK1 222 TSK2 222 TSK2 333 TSK2 444 TSK3 111 TSK3 333
消息表架构:
Subject Receiver Sender Content Overdue Task 111 000 Task TSK1 is overdue. Overdue Task 222 000 Task TSK1 is overdue. Overdue Task 222 000 Task TSK2 is overdue. Overdue Task 333 000 Task TSK2 is overdue. Overdue Task 444 000 Task TSK2 is overdue.
因此,代码将让所有人被分配到一个过期的任务(即比今天更早的EndDate和!= 100%完成)并留下一条消息告诉他们
我认为真正的问题是我使用select查询从数据库中分配过期任务的人员,然后在调用数据库插入消息之前使用C#代码组成消息和事务。
答案 0 :(得分:3)
您可以将工作委托给后台线程。创建一个功能来完成工作,并启动它:
new Thread(
() => SendALotOfMessagesByBadDesign(par1)
).Start();
重新启动IIS或回收应用程序池会中断后台线程,但这也会在您当前的解决方案中发生。
答案 1 :(得分:1)
用这个替换你的循环:
BEGIN TRANSACTION
INSERT INTO Messages
(Subject, Receiver, Sender, Content)
SELECT
'Overdue Task', t.TaskID, '000', 'Task '+CONVERT(varchar,t.TaskID)+' is overdue.'
FROM Tasks t
INNER JOIN Assignments a ON t.TaskID=a.TaskID
LEFT OUTER JOIN Messages m ON t.TaskID=m.Receiver
WHERE t.EndDate<GETDATE() AND PercentComplete<100
AND m.Receiver IS NULL
DELETE Messages
FROM Messages
INNER JOIN Tasks ON Messages.Receiver=Tasks.TaskID AND PercentComplete=100
COMMIT
这只会插入未完成的过期任务,而且还没有消息。它将从已完成的任务中删除消息。你必须添加你选择的错误处理。
修改强>
由于您无法将消息加入任务,因此您无法像我上面那样进行删除。如果您没有时间在EndDate列上,则可以在午夜之后将其作为SQL Server作业运行,作为该作业的一部分,首先截断表,然后插入所需的内容。我确保在任务标记为100完成时删除邮件
答案 2 :(得分:0)
另外,旋转 脱线影响其他网络 应用程序在同一台服务器上?
假设Web服务器有多个CPU,我想您可以将此Web应用程序分配给自己的应用程序池,并将关联设置为特定处理器以限制对其他Web应用程序的影响。 http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/cpu
我从来没有这样做,我只是把它扔在那里“在可能性范围内”。我不知道是否可取。