SridharVenkat
SridharVenkat

Reputation: 656

WCF Fire Async Task (Fire and forget style) - Resource concerns

We have an ASP.NET MVC 3 application that interacts with WCF layer for service logic. On one particular functionality the service layer takes long time to responsd, the UI timesout on svc. The processing itself is huge so it's bound to take more time. We don't want users to see timeouts, so we planned to display partial success status and keep updating the UI with status.

We are planning to split the process into various steps, some of them in kinda of fire and forget fashion. Now when user requests for details

  1. Svc processes mandatory steps, returns response

  2. Svc also initiates a Task fires it using below(TPL), this performs non-mandatory steps

    Task.Factory.StartNew(FireAway);
    
  3. UI keeps polling to update status

  4. Tasks update completion status in DB

  5. UI polls and retrives completion status and displays in UI

Concerns...

  1. Does the Thread that processes Tasks will get reused (no listener attached), will this cause too much Thread creation or leakage?
  2. How about resources, will Fire and forget tasks cause and Memory leakage? Task functionality is to connect to multiple DBs and update status.
  3. I am not happy with design (we have to do this as quick fix), any better design patterns?

Upvotes: 2

Views: 1990

Answers (2)

Andrew Steitz
Andrew Steitz

Reputation: 2007

Marcin is correct. I upvoted that answer but thought I should expound. TPL in and of itself will not cause resource leakage. If you experience any resource leaks, please read this article. :-)

Marcin is also correct about the possibility of IIS recycling the AppPool and causing "data loss." We have a similar scenario and found that to happen more often than one would think. We redesigned our service slightly to receive a trigger message that informed it "hey, you have some data waiting for you in the database." This eliminates the need for polling. The function performed is a multistep process and each step updates the database so that if the service is restarted/recycled midstream it can pickup where it left off. You do not need to turn it into a Windows Service, but you can if you want to or need to move it to a different, non-web server.

If you are worried about TOO MANY threads being spooled up, check out this SO Q&A.

Pedagogical note: async and fire-and-forget are NOT the same. Async means "I want an answer but can't wait around so call me later, once you are done." Fire-and-forget means "Here is some data/info. Do what you do with it but DON'T call me. I don't care or I will call back later, if I want to know."

Upvotes: 1

Marcin Waligora
Marcin Waligora

Reputation: 540

First off by creating

Task.Factory.StartNew(FireAway);

you don't explicitly create a new thread. That task will use threads from thread pool but there is no 1:1 mapping from task to thread. For example if your task will spend long time doing I/O operations underlying thread can be used by another request.

The design you've specified should not cause any resource (thread or memory) leakage provided you have done everything correct. The design from technical perspective is correct yet it can be greatly improved.

This design is prone to IIS restarts killing this task mid-run. Better approach would be to have your web requests store request information in Database and have some Windows Service on the backend pick it up and process it. The UI could simply check the databse for updates for a given task.

Upvotes: 1

Related Questions