0

I need to call a very slow database method from a web page. It seems I have lots of options ranging from using BackgroundWorker, Task.Run() and Thread.Start()

Which is most appropriate for my scenario?

Currently I have:

Task.Run(() =>
{
    using (DAL.StatsDAL data = new DAL.StatsDAL()) 
    {
        data.UpdateStatistics(entryID, entryTtype);
    }
});

I do not need a result from this (currently) but I just need to "fire and forget". Also I'm guessing any potential error messages which occur on this thread will not get caught by my exception handler (ELMAH) as the HttpContext might have disappeared by then?

Edit: This is ASP.NET WebForms 4.5.1.

Edit 2: I expect the task to complete in around 1 second (max), so I'm really just trying to avoid the 1 second delay every time the user clicks between pages

NickG
  • 9,315
  • 16
  • 75
  • 115
  • @YuvalItzchakov I'm not sure if this question is about MVC. It seems more like a WF issue.. :\ – Matías Fidemraizer Sep 24 '15 at 11:52
  • @MatíasFidemraizer Windows Forms? The OP tagged it with `ASP.NET`. – Yuval Itzchakov Sep 24 '15 at 11:52
  • @Matias tagged ASP.NET, OP mentions ELMAH and HttpContext. Pretty sure it's ASP.NET. – CodeCaster Sep 24 '15 at 11:53
  • WF might mean Web Forms, regular aspx? – Sandip Bantawa Sep 24 '15 at 11:55
  • @YuvalItzchakov Web Forms............ – Matías Fidemraizer Sep 24 '15 at 11:56
  • @CodeCaster While WebForms is almost dead for future developments, a lot of people still refers to WebForms as just ASP.NET :D – Matías Fidemraizer Sep 24 '15 at 11:56
  • @MatíasFidemraizer It's still the same ASP.NET environment. The answer on the duplicate will give him what he needs. – Yuval Itzchakov Sep 24 '15 at 11:57
  • @YuvalItzchakov It seems like you're correct, BTW who knows what version of WebForms is using OP, maybe OP needs to use the ASP.NET 2.0 old-school way of registering async tasks – Matías Fidemraizer Sep 24 '15 at 11:58
  • The duplicate is actually pretty horrible. The approaches there also mention that they are **not for tasks that should actually complete**. There is a canonical Q&A on how to properly do background tasks in ASP.NET, but I can't find it. – CodeCaster Sep 24 '15 at 11:58
  • @CodeCaster OP doesn't seem to care for completion. The use of `BackgroundTaskManager` is pretty much what he needs, disregarding the internal delegate actually being `Task` returning. – Yuval Itzchakov Sep 24 '15 at 12:00
  • This might be helpful: https://msdn.microsoft.com/en-us/library/aa480412.aspx – Sandip Bantawa Sep 24 '15 at 12:02
  • [This](http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) will probably answer all your questions. – Yuval Itzchakov Sep 24 '15 at 12:02
  • @Yuval depending on the technology being used, an AppDomain teardown in OP's case can actually cause a database transaction to not be committed. You hardly ever want to use that suggestion, unless you really don't care that the action you start is actually completed, or can be repeated. Which indeed may be the case for statistic calculations, but still. I'd say "use Hangfire", but that's GPL. – CodeCaster Sep 24 '15 at 12:03

1 Answers1

0

You're gonna be doing a lot of, you really want to look into async/await in .Net 4.5.

https://msdn.microsoft.com/en-us/library/hh191443.aspx

Paul Coghill
  • 667
  • 6
  • 27
  • 1
    _"Task.Run() is fine"_ - no, it's not. Read [How to run Background Tasks in ASP.NET](http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx). And async/await has little to do with background tasks. – CodeCaster Sep 24 '15 at 11:46
  • Fair enough, removed. – Paul Coghill Sep 24 '15 at 11:52
  • @CodeCaster The methods in that article seem to assume *very* long running tasks (minutes). I'm just trying to allow the page render to complete quickly when the "slow" code will delay it for a few hundred milliseconds so I was assuming I could make do with something simpler. – NickG Sep 24 '15 at 12:05
  • @NickG if you can handle the code _not_ running to completion once in a while, then you're fine. When IIS decides it is time to recycle your application pool, it will do so after handling the last request. Any background thread is not considered in that regard, and will be terminated. – CodeCaster Sep 24 '15 at 12:06
  • @codecaster I may lose the odd page view statistic, but realistically, if it typically completes in around half a second, how often might it not fire? – NickG Sep 24 '15 at 12:07
  • @NickG what you want is message queue, its operation is completely independent regardless of concept of threading where still OS handles everything. – Sandip Bantawa Sep 24 '15 at 12:15
  • @NickG I can't really give you the numbers. You just have to realize it _can_ happen that your task won't finish, and act accordingly. Realistically, it'll be in the order of maybe once a day to once a year, depending on lots and lots of variables. If the task **must always finish and can never fail** (by being terminated), use a dedicated service. – CodeCaster Sep 24 '15 at 12:21