【问题标题】:Background Threading in ASP.NET and Impact on PerformanceASP.NET 中的后台线程和对性能的影响
【发布时间】:2009-06-04 14:44:37
【问题描述】:

我当前的网站设置为在有人首次登录该应用程序时为某些人留言。留下的消息数量可能在 1000 到 10000 之间,每条消息都是一个查询,所有查询都在一个事务语句中。

是的,我知道这似乎是糟糕的设计,这不是我的问题。

目前,当用户登录时,服务器必须先完成所有查询,然后用户才能实际执行任何操作。我的意思是,用户查看登录屏幕,直到超时启动并重置页面。最近我们已经等待了长达 30 分钟(!)

我想把这个过程放在一个线程上,这样用户就可以登录网站,做他/她需要做的任何活动,查看/删除他们的消息,同时不受消息传递者的阻碍。

我的问题是,简单地分拆一个新线程来处理这个过程是否可以解决问题(即允许用户在传递者留下消息时工作)?另外,分离线程是否会影响同一服务器上的其他 Web 应用程序?

编辑基于 KM 的 cmets

简化模式:

任务表:

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

分配表:

任务 ID 资源 ID TSK1 111 TSK1 222 TSK2 222 TSK2 333 TSK2 444 TSK3 111 TSK3 333

消息表架构:

主题 接收者 发送者 内容 逾期任务 111 000 任务 TSK1 逾期。 逾期任务 222 000 任务 TSK1 逾期。 逾期任务 222 000 任务 TSK2 逾期。 逾期任务 333 000 任务 TSK2 逾期。 逾期任务 444 000 任务 TSK2 逾期。

因此,代码将让所有人分配到一个过期任务(即 EndDate 早于今天并且 != 100% 完成)并给他们留言告诉他们

我认为真正的问题是我正在使用选择查询从数据库中获取分配给过期任务的人员,然后在调用数据库插入消息之前使用 C# 代码编写消息和事务。

【问题讨论】:

  • 提供有关如何将消息加入任务的信息
  • 消息未加入任务。我只需要任务 ID,因此我可以将它放在消息正文中。需要将资源加入到消息中,因为它们将读取它们。

标签: asp.net sql-server performance multithreading


【解决方案1】:

您可以将工作委托给后台线程。创建一个函数来完成这项工作,然后像这样启动它:

new Thread(
    () => SendALotOfMessagesByBadDesign(par1)
    ).Start();

重新启动 IIS 或回收应用程序池会中断后台线程,但这也发生在您当前的解决方案中。

【讨论】:

  • +1 因为IIS工作进程随时可能死掉,后台线程的工作会丢失。
【解决方案2】:

用这个替换你的循环:

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 完成时删除消息

【讨论】:

  • 天哪,这太近了!但是 Messages 表中的 Receiver 字段是资源 ID,而不是任务 ID。我将 Insert 语句修复为我需要的,但我不知道如何修复 Delete 语句
【解决方案3】:

还有,旋转 脱线影响其他网络 同一服务器上的应用程序?

假设 Web 服务器有多个 CPU,我想您可以将此 Web 应用程序分配给它自己的应用程序池,并将亲和性设置为特定的处理器,以限制对其他 Web 应用程序的影响。 http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/cpu

我从来没有这样做过,我只是把它作为“可能性范围内”扔在那里。不知道好不好用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多