Question

I am using the following Task based programming (TPL) in a page that is not an Async page.

My question is: Is it ok to use TPL (i.e. Task Parallel Library) for creating multi-threaded calls in an ASP.Net page, or one must always use the inbuilt Async page feature for multi-threading in an ASP.Net page? So far the TPL approach hasn't created any problems, but just wanted to be sure in case I missed some important point/hidden risks with using TPL in an ASP.Net page.

       Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Method1(); 
                        success4 = true;
                    }
                    catch (Exception e4)
                    {
                        success4 = false;
                        ex = e4.ToString();
                    }
                }),
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Method2();
                        success5 = true;
                    }
                    catch (Exception e5)
                    {
                        success5 = false;
                        ex = e5.ToString();
                    }
                }),
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        Method3();
                        success6 = true;
                    }
                    catch (Exception e6)
                    {
                        success6 = false;
                        ex = e6.ToString();
                    }
                })
            };
   Task.WaitAll(tasks);

UPDATE 1:

As pointed out in the answer, using TPL in ASP.Net would limit scalability of the ASP.Net app, since each task uses a thread from ASP.Net thread pool, and at the same time keeps the original thread of the page in a blocked state.
I am now thinking about using TPL when calling the method in an Async page as in code below, to take advantage of more powerful processing that parallelism brings. But I will investigate this further to see whether in a real situation, TPL will make it better or worse for the async method.

private void DoTask4(object[] paras)
    {
        Parallel.Invoke(() =>
            {
               try
               {
                   Method4( paras);
               }
               catch (Exception e4)
               {
                   success4 = false;
                   //log the exception
               }
           });
    }

    IAsyncResult BeginAsyncOperation4(object sender, EventArgs e, AsyncCallback cb, object state)
    {
        task4 = new AsyncTaskDelegate(DoTask4);
        IAsyncResult result = task4.BeginInvoke(state as object[], cb, "task4");
        return result;
    }

    void EndAsyncOperation4(IAsyncResult ar)
    {
        task4.EndInvoke(ar);
        if (success4 == null)
        {
            success4 = true;
        }
    }

    void TimeoutAsyncOperation4(IAsyncResult ar)
    {
        success4 = false;
    }

UPDATE 2:

Finally, as pointed out in the answer, even using TPL with Async page method would also cause a thread from thread pool to get used, which again means our ASP.Net scalability will be an issue. So, its best not to use TPL inside an Async page.

Was it helpful?

Solution

This approach may seriously hurt the server scalability, because it uses extra theads and blocks the request thread. Suppose Method1..3 are responsible for some IO-bound work. If you can't use async ASP.NET controllers, you still can start an async IO-bound operation with AsyncManager (e.g., like this) or with PageAsyncTask (for classic ASP.NET) and avoid blocking.

If however you need to do some CPU-bound work (as opposed to IO-bound work), just do it on the same request thread, step by step, rather than in parallel. Otherwise, each Task.Factory.StartNew may be putting another incoming HTTP request on hold, depending on the server load. Because you probably want to serve as many concurrent HTTP requests as possible, you should avoid parallelizing CPU-bound work.

That said, your code might be fine for an intranet web app with low number of concurrent HTTP requests. You could do so if you want to speed up the response delivery for an individual request.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top