Long-running ASP.NET tasks

后端 未结 4 2157
猫巷女王i
猫巷女王i 2020-11-27 23:10

I know there\'s a bunch of APIs out there that do this, but I also know that the hosting environment (being ASP.NET) puts restrictions on what you can reliably do in a separ

相关标签:
4条回答
  • 2020-11-27 23:41

    Have thought about the use the Workflow Foundation instead of your custom implementation? It also allows you to persist states. Tasks could be defined as workflows in this case.

    Just some thoughts...

    Michael

    0 讨论(0)
  • 2020-11-27 23:46

    Use a simple background tasks / jobs framework like Hangfire and apply these best practice principals to the design of the rest of your solution:

    • Keep all actions as small as possible; to achieve this, you should-
    • Divide long running jobs into batches and queue them (in a Hangfire queue or on a bus of another sort)
    • Make sure your small jobs (batched parts of long jobs) are idempotent (have all the context they need to run in any order). This way you don't have to use a quete which maintains a sequence; because then you can
    • Parallelise the execution of jobs in your queue depending on how many nodes you have in your web server farm. You can even control how much load this subjects your farm to (as a trade off to servicing web requests). This ensures that you complete the whole job (all batches) as fast and as efficiently as possible, while not compromising your cluster from servicing web clients.
    0 讨论(0)
  • 2020-11-27 23:57

    Have a look at NServiceBus

    NServiceBus is an open source communications framework for .NET with build in support for publish/subscribe and long-running processes.

    It is a technology build upon MSMQ, which means that your messages don't get lost since they are persisted to disk. Nevertheless the Framework has an impressive performance and an intuitive API.

    0 讨论(0)
  • 2020-11-27 23:58

    John,

    I agree that ASP.NET is not suitable for Async tasks as you have described them, nor should it be. It is designed as a web hosting platform, not a back of house processor.

    We have had similar situations in the past and we have used a solution similar to what you have described. In summary, keep your WCF service under ASP.NET, use a "Queue" table with a Windows Service as the "QueueProcessor". The client should poll to see if work is done (or use messaging to notify the client).

    We used a table that contained the process and it's information (eg InvoicingRun). On that table was a status (Pending, Running, Completed, Failed). The client would submit a new InvoicingRun with a status of Pending. A Windows service (the processor) would poll the database to get any runs that in the pending stage (you could also use SQL Notification so you don't need to poll. If a pending run was found, it would move it to running, do the processing and then move it to completed/failed.

    In the case where the process failed fatally (eg DB down, process killed), the run would be left in a running state, and human intervention was required. If the process failed in an non-fatal state (exception, error), the process would be moved to failed, and you can choose to retry or have human intervantion.

    If there were multiple processors, the first one to move it to a running state got that job. You can use this method to prevent the job being run twice. Alternate is to do the select then update to running under a transaction. Make sure either of these outside a transaction larger transaction. Sample (rough) SQL:

    UPDATE InvoicingRun
    SET Status = 2 -- Running
    WHERE ID = 1
        AND Status = 1 -- Pending
    
    IF @@RowCount = 0
        SELECT Cast(0 as bit)
    ELSE
        SELECT Cast(1 as bit)
    

    Rob

    0 讨论(0)
提交回复
热议问题