none
Consequence of a spawn and forget thread RRS feed

  • Question

  • The below code snippet is from a MVC4 web application.  It is a method in a Controller.  This method responds to an order being submitted.  After saving the order to the database, if some high intensive IO processing is required, the method invokes a delegate on separate thread for that.  Meanwhile the customer does not need to wait on this processing and the method returns right away with the receipt.

    My expectation is this thread will die upon completion and no longer consume server resources.  However, I am no longer sure of that.  To not complicate this issue, I will leave that part out of the question for now.  So the question is what is the consequence of spawning a thread and forgetting about it?

    The server is a Windows 2003 Web edition OS (32 bit) and of is running IIS 6.0.  Our load is very small, orders placed range from 5 to 100 per day.  If only 50% place orders, that is 3-50 orders per day.

    public JsonResult SubmitOrder(Order order)
    {
    //Process credit card
    
    //Save Order
    
    //Create, save and FTP (to lab) order XML.  FTP ordered high quality photos to lab
    	if (IsXMLRequired(order))//check for ordered products that require lab processing
    	{
    		var txOrderDel = new TransmitOrderDelegate(TransmitOrder);
    		txOrderDel.BeginInvoke(serverName, rwEvent.MarketName, rwEvent.AcctNo, ref order, ref dsOrder2, null, null);                
    	}
                
    	//Return to client and present Receipt view.
    	return Json(new { message = "Order Submitted", order = order, downloads = downLoadables});
    }
    


    WhiskeyRomeoLima

    Friday, July 12, 2013 4:05 PM

Answers

All replies

  • Creating a thread is generally a "fire and forget" approach.  When the thread terminates its resources will be cleaned up.  Where you have to start worrying is when you're using tasks which might have results.  It really depends upon how the async call is occurring.  In your case you are using Delegate.BeginInvoke.  The documentation for this method states that you must ensure that EndInvoke is also called so resources are cleaned up.  This is undoubtedly because of the implementation details.  Therefore in your given code you need to call EndInvoke.  However if you were to create your own thread (using new Thread) then there is no cleanup needed.

    Michael Taylor
    http://msmvps.com/blogs/p3net

    Friday, July 12, 2013 4:13 PM
    Moderator
  • I am totally new to multi-threading but . . .

    Simply replacing the above code with . . .

          Thread txThread = new Thread(new ThreadStart(() => TransmitOrder(serverName, rwEvent.MarketName, rwEvent.AcctNo, ref order, ref dsOrder2)
    );
    
          txThread.Start();

    avoids having to call EndInvoke which could end up blocking unless I called it on yet another thread?



    WhiskeyRomeoLima


    Friday, July 12, 2013 4:48 PM
  • I would actually recommand using Task.Factory.StartNew instead of a new Thread.  This will use a ThreadPool thread (fewer resources used):

    Task.Factory.StartNew( () => TransmitOrder(serverName, rwEvent.MarketName, rwEvent.AcctNo, ref ...));


    Reed Copsey, Jr. - http://reedcopsey.com - If a post answers your question, please click Mark As Answer on that post. If you find a post helpful, please click Vote as Helpful.

    Friday, July 12, 2013 5:01 PM
    Moderator