The AsyncTimeout filter doesn't workshttp://forums.asp.net/t/1564303.aspx/1?The+AsyncTimeout+filter+doesn+t+worksMon, 14 Jun 2010 17:56:49 -040015643033890129http://forums.asp.net/p/1564303/3890129.aspx/1?The+AsyncTimeout+filter+doesn+t+worksThe AsyncTimeout filter doesn't works <p>I was trying to apply AsyncTimeout attribute on my Async aciton of a&nbsp;Async controller.&nbsp; It&nbsp;looks like not able to&nbsp;produce a TimeoutException.&nbsp; Does anyone&nbsp;know&nbsp;how to use this attribute?</p> <p>&nbsp;</p> <p>Here is my sample code&nbsp;for testing this attribute:</p> <pre class="prettyprint">using System; using System.Web.Mvc; using System.Threading; namespace MvcApplication1.Controllers { public class HomeController : AsyncController { [AsyncTimeout(2)] public void IndexAsync() { Thread.Sleep(3000); } public ActionResult IndexCompleted() { return View(); } } }</pre> <p><br> &nbsp;</p> <p>&nbsp;</p> 2010-06-01T18:41:00-04:003890167http://forums.asp.net/p/1564303/3890167.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p>The [AsyncTimeout] attribute controls the maximum time to wait when the XxAsync() method kicks off an async operation, like making a network request. &nbsp;The timer doesn't start until the IndexAsync() method returns. &nbsp;Since Thread.Sleep() is a synchronous operation, it blocks IndexAsync() from returning in your example.</p> 2010-06-01T19:13:59-04:003890875http://forums.asp.net/p/1564303/3890875.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p>This isn't what I expected. &nbsp;I was expected&nbsp;AsyncController's AsyncAction as an independent thread to run code. &nbsp;So I have to use Async model to write code in my AsyncController, right?</p> <p>Thanks!</p> 2010-06-02T02:11:54-04:003890902http://forums.asp.net/p/1564303/3890902.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p></p> <blockquote><span class="icon-blockquote"></span> <h4>levib</h4> <p>The [AsyncTimeout] attribute controls the maximum time to wait when the XxAsync() method kicks off an async operation, like making a network request. &nbsp;The timer doesn't start until the IndexAsync() method returns. &nbsp;Since Thread.Sleep() is a synchronous operation, it blocks IndexAsync() from returning in your example.</p> <p></p> </blockquote> &nbsp; <p></p> <p>AFAIK that action executing the code is asynchronous,</p> <p>As given in Microsoft MVC Book,<br> </p> <blockquote><span class="icon-blockquote"></span> <h4>Dino</h4> <br> When the action invoker sends a notification that it is about to execute the action, the thread engaged is still the original ASP.NET thread that picked up the request from the Web server queue. The code running at this point is the trigger method, usually in the form of an xxxAsync method, as the following code shows: <p></p> <p>public void PerformLengthTaskAsync(SomeData data)<br> {<br> &nbsp;// Process input<br> &nbsp;. . .<br> &nbsp;// Post a work item to a component that can result<br> &nbsp;// in a lengthy operation (for example, invoke a Web service)<br> &nbsp;. . .<br> &nbsp;// That's all for nowthe action is being executed elsewhere.<br> &nbsp;// All that remains to be done is wait for it to terminate;<br> &nbsp;// for this task, we don't want to squander an ASP.NET thread.<br> &nbsp;return;<br> }<br> When the trigger method returns, the lengthy action is running in the care of some other thread, possibly on some other process. The asynchronous action invoker manages to sync up with the ASP.NET runtime so that a completion port is used to monitor the completion of the operation. When this happens, the ASP.NET runtime puts the requests back in circulation with a special flag that indicates it only needs to complete its second half. The first available ASP.NET thread picks up the request and begins processing it.<br> </p> </blockquote> <p></p> <p>I think AsyncTimeout is expressed in milliseconds not in seconds<br> </p> <blockquote><span class="icon-blockquote"></span> <h4>Dino</h4> <br> In addition, you can set a timeout on a per-controller or per-action basis by using the AsyncTimeout attribute: <p></p> <p>[AsyncTimeout(3000)]</p> <p>The attribute is invoked by ASP.NET MVC before the asynchronous action method executes. The duration is expressed in milliseconds and defaults to 30 seconds. By default, all methods are subject to this timeout. If you dont want any timeout, you set that preference explicitly by using the NoAsyncTimeout attribute. No timeout is equivalent to setting the timeout to the value of System.Threading.Timeout.Infinite. By setting the Timeout property of the AsyncManager object, on the other hand, you can set a new global timeout value that applies to any call unless its overridden by attributes at the controller or action level.</p> <p></p> </blockquote> <p></p> <p>You can check the current thread property to find that which thread is executing, <br> Thread.CurrentThread.IsThreadPoolThread<br> Thread.CurrentThread.Name<br> etc..</p> <p>&nbsp;</p> 2010-06-02T02:28:47-04:003891190http://forums.asp.net/p/1564303/3891190.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p>Documentation for the AsyncController can be found at <a href="http://msdn.microsoft.com/en-us/library/ee728598.aspx"> http://msdn.microsoft.com/en-us/library/ee728598.aspx</a>. &nbsp;In particular, look at the diagram under the <i>Processing Asynchronous Requests</i> section. &nbsp;The XxAsync() method executes on Thread A; the XxCompleted() method executes on Thread B. &nbsp;The XxAsync() / XxCompleted() method pair constitutes a single logical &quot;action method&quot;, which is why the dashed line in the diagram goes through the block marked &quot;action method&quot;. &nbsp;Note that Thread A and Thread B might actually be the same thread.</p> <p>The [AsyncTimeout] attribute affects only that dashed line. &nbsp;The attribute says &quot;if the asynchronous action method has not completed within a set amount of time, fail the request.&quot; &nbsp;But note that since the attribute affects the dashed line and that the dashed line occurs between XxAsync() and XxCompleted(),&nbsp;<i>the timer does not start until after the XxAsync() method returns</i>.</p> <p>This might seem counterintuitive but actually makes sense. &nbsp;Consider what would happen if the timer were to start before the XxAsync() method executes. &nbsp;If the timer expires while the XxAsync() method is executing, nothing happens as the MVC runtime can't interrupt the main thread processing the ASP.NET request. &nbsp;Calling Thread.Abort() is not an option since it's a Very Bad Thing to abort a thread which is not under your control, as it could lead to AppDomain destabilization.</p> <p>Combine this with the fact that the XxAsync() method is supposed to return immediately without blocking - its only purpose is to kick off an asynchronous operation, after all - and one concludes that the only useful point at which to start the timeout timer is after the XxAsync() method returns and the main thread has returned back to the ASP.NET thread pool.</p> 2010-06-02T04:32:31-04:003892828http://forums.asp.net/p/1564303/3892828.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p></p> <blockquote><span class="icon-blockquote"></span> <h4>levib</h4> Combine this with the fact that the XxAsync() method is supposed to return immediately without blocking - its only purpose is to kick off an asynchronous operation, after all - and one concludes that the only useful point at which to start the timeout timer is after the XxAsync() method returns and the main thread has returned back to the ASP.NET thread pool.</blockquote> &nbsp; <p></p> <p>&nbsp;</p> <p>Is you check Thread.CurrentThread properties in both XxAsync() and XxCompleted(), like</p> <p>Thread.CurrentThread.IsThreadPoolThread<br> Thread.CurrentThread.Name&nbsp;&nbsp; etc</p> 2010-06-02T17:50:46-04:003922462http://forums.asp.net/p/1564303/3922462.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p></p> <blockquote><span class="icon-blockquote"></span> <h4>imran_ku07</h4> <p></p> <p>Is you check Thread.CurrentThread properties in both XxAsync() and XxCompleted(), like</p> <p>Thread.CurrentThread.IsThreadPoolThread<br> Thread.CurrentThread.Name</p> <p></p> </blockquote> <p></p> <p>After my checking i found that the thread is same both in Application_Start and XxAsync.</p> <p>Here is the proof,</p> <p>public ActionResult Index()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Debug.WriteLine(&quot;Index&quot;&#43;AppDomain.GetCurrentThreadId().ToString());</p> <p>}</p> <p>protected void Application_BeginRequest()<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Debug.WriteLine(&quot;Begin&quot; &#43; AppDomain.GetCurrentThreadId().ToString());<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p> <p>I was confused from the Microsoft Dino's book example,</p> <p></p> <blockquote><span class="icon-blockquote"></span> <p></p> <p>public void PerformTaskAsync(SomeData data)<br> {<br> &nbsp;&nbsp; &nbsp;AsyncManager.OutstandingOperations.Increment();<br> &nbsp;&nbsp; &nbsp;var response = new SomeResponse();<br> &nbsp;&nbsp; &nbsp;. . .<br> &nbsp;&nbsp; &nbsp;// Do some remote work (for example, invoke a service)<br> &nbsp;&nbsp; &nbsp;. . .<br> &nbsp;&nbsp; &nbsp;// Terminate operations, and prepare data for the finalizer<br> &nbsp;&nbsp; &nbsp;AsyncManager.Parameters[&quot;data&quot;] = response;<br> &nbsp;&nbsp; &nbsp;AsyncManager.OutstandingOperations.Decrement();<br> }</p> <p></p> </blockquote> <p></p> <p>I think this is not correct to call AsyncManager.OutstandingOperations.Decrement() inside XxAsync. Because you are saying that asynchronous method starts after method returns. What do you say levib</p> <p></p> <blockquote><span class="icon-blockquote"></span> <h4>levib</h4> Documentation for the AsyncController can be found at <a href="http://msdn.microsoft.com/en-us/library/ee728598.aspx"> http://msdn.microsoft.com/en-us/library/ee728598.aspx</a>. </blockquote> <p></p> <p>Thanks you also for the link. I appreciate the Rick article and Rick example.</p> <p><br> </p> <p>Now We can say that <b>XxAsync is synchronous</b> but the method it starts from XxAsync using Begin/End pattern is asynchronous.</p> <p>What do you say Levib?</p> <p>Also can you tell me how ASP.NET knows that XxAsync starts&nbsp; asynchrnous task/tasks?</p> <p><br> </p> 2010-06-12T13:15:50-04:003926107http://forums.asp.net/p/1564303/3926107.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p></p> <blockquote><span class="icon-blockquote"></span> <h4>imran_ku07</h4> I think this is not correct to call AsyncManager.OutstandingOperations.Decrement() inside XxAsync. Because you are saying that asynchronous method starts after method returns. What do you say levib</blockquote> <p></p> <p>Correct. &nbsp;Generally Decrement() shouldn't be called from the XxAsync() method, though there are some rare exceptions. &nbsp;I'm not familiar with the example you posted, though, so I can't really comment on it without the full context.</p> <p></p> <blockquote><span class="icon-blockquote"></span> <h4>imran_ku07</h4> Now We can say that <span class="Apple-style-span" style="font-weight:bold">XxAsync is synchronous</span> but the method it starts from XxAsync using Begin/End pattern is asynchronous.</blockquote> <p></p> <p>This is true in a sense, just like if you call a BeginXx / EndXx method (like Stream.BeginRead(), EndRead()). &nbsp;The methods are themselves synchronous, and nothing else can happen on the thread on which they're executing until the methods return. &nbsp;Their jobs are to&nbsp;kick off an asynchronous task (BeginRead) or retrieve and join the results of an asynchronous task (EndRead).</p> <p></p> <blockquote><span class="icon-blockquote"></span> <h4>imran_ku07</h4> Also can you tell me how ASP.NET knows that XxAsync starts&nbsp; asynchrnous task/tasks?</blockquote> <p></p> <p>It doesn't, hence the Increment() / Decrement() counters are necessary.</p> 2010-06-14T17:44:42-04:003926123http://forums.asp.net/p/1564303/3926123.aspx/1?Re+The+AsyncTimeout+filter+doesn+t+worksRe: The AsyncTimeout filter doesn't works <p>Thank you very much for your reply and time.</p> <p></p> <blockquote><span class="icon-blockquote"></span> <h4>levib</h4> It doesn't, hence the Increment() / Decrement() counters are necessary.</blockquote> <p></p> <p>Now, we can say that XXCompleted is called when OutstandingOperations is become 0?</p> <p>The example posted from this book,</p> <p>http://www.microsoft.com/learning/en/us/Books.aspx?Id=13989&amp;locale=en-us</p> 2010-06-14T17:56:49-04:00