I was trying to apply AsyncTimeout attribute on my Async aciton of a Async controller. It looks like not able to produce a TimeoutException. Does anyone know how to use this attribute?
Here is my sample code for testing this attribute:
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();
}
}
}
The [AsyncTimeout] attribute controls the maximum time to wait when the XxAsync() method kicks off an async operation, like making a network request. The timer doesn't start until the IndexAsync() method returns. Since Thread.Sleep() is a synchronous operation,
it blocks IndexAsync() from returning in your example.
Marked as answer by Doggy8088 on Jun 02, 2010 06:52 PM
This isn't what I expected. I was expected AsyncController's AsyncAction as an independent thread to run code. So I have to use Async model to write code in my AsyncController, right?
The [AsyncTimeout] attribute controls the maximum time to wait when the XxAsync() method kicks off an async operation, like making a network request. The timer doesn't start until the IndexAsync() method returns. Since Thread.Sleep() is a synchronous operation,
it blocks IndexAsync() from returning in your example.
AFAIK that action executing the code is asynchronous,
As given in Microsoft MVC Book,
Dino
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:
public void PerformLengthTaskAsync(SomeData data)
{
// Process input
. . .
// Post a work item to a component that can result
// in a lengthy operation (for example, invoke a Web service)
. . .
// That's all for now—the action is being executed elsewhere.
// All that remains to be done is wait for it to terminate;
// for this task, we don't want to squander an ASP.NET thread.
return;
}
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.
I think AsyncTimeout is expressed in milliseconds not in seconds
Dino
In addition, you can set a timeout on a per-controller or per-action basis by using the AsyncTimeout attribute:
[AsyncTimeout(3000)]
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 don’t 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 it’s overridden by attributes at the controller or action level.
You can check the current thread property to find that which thread is executing,
Thread.CurrentThread.IsThreadPoolThread
Thread.CurrentThread.Name
etc..
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
Documentation for the AsyncController can be found at
http://msdn.microsoft.com/en-us/library/ee728598.aspx. In particular, look at the diagram under the
Processing Asynchronous Requests section. The XxAsync() method executes on Thread A; the XxCompleted() method executes on Thread B. The XxAsync() / XxCompleted() method pair constitutes a single logical "action method", which is why the dashed line
in the diagram goes through the block marked "action method". Note that Thread A and Thread B might actually be the same thread.
The [AsyncTimeout] attribute affects only that dashed line. The attribute says "if the asynchronous action method has not completed within a set amount of time, fail the request." But note that since the attribute affects the dashed line and that the dashed
line occurs between XxAsync() and XxCompleted(), the timer does not start until after the XxAsync() method returns.
This might seem counterintuitive but actually makes sense. Consider what would happen if the timer were to start before the XxAsync() method executes. 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. 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.
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.
Marked as answer by Doggy8088 on Jun 02, 2010 06:51 PM
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.
Is you check Thread.CurrentThread properties in both XxAsync() and XxCompleted(), like
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
I was confused from the Microsoft Dino's book example,
public void PerformTaskAsync(SomeData data)
{
AsyncManager.OutstandingOperations.Increment();
var response = new SomeResponse();
. . .
// Do some remote work (for example, invoke a service)
. . .
// Terminate operations, and prepare data for the finalizer
AsyncManager.Parameters["data"] = response;
AsyncManager.OutstandingOperations.Decrement();
}
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
Thanks you also for the link. I appreciate the Rick article and Rick example.
Now We can say that XxAsync is synchronous but the method it starts from XxAsync using Begin/End pattern is asynchronous.
What do you say Levib?
Also can you tell me how ASP.NET knows that XxAsync starts asynchrnous task/tasks?
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
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
Correct. Generally Decrement() shouldn't be called from the XxAsync() method, though there are some rare exceptions. I'm not familiar with the example you posted, though, so I can't really comment on it without the full context.
imran_ku07
Now We can say that XxAsync is synchronous but the method it starts from XxAsync using Begin/End pattern is asynchronous.
This is true in a sense, just like if you call a BeginXx / EndXx method (like Stream.BeginRead(), EndRead()). The methods are themselves synchronous, and nothing else can happen on the thread on which they're executing until the methods return. Their jobs
are to kick off an asynchronous task (BeginRead) or retrieve and join the results of an asynchronous task (EndRead).
imran_ku07
Also can you tell me how ASP.NET knows that XxAsync starts asynchrnous task/tasks?
It doesn't, hence the Increment() / Decrement() counters are necessary.
Marked as answer by ricka6 on Jun 21, 2010 05:49 PM
"And whoever is removed away from the Fire and admitted to Paradise, he indeed is successful." (The Holy Quran)
Excellent Windows VPS Hosting Imran Baloch MVP, MVB, MCP, MCTS, MCPD
Marked as answer by ricka6 on Jun 21, 2010 05:49 PM
Doggy8088
Member
41 Points
110 Posts
The AsyncTimeout filter doesn't works
Jun 01, 2010 06:41 PM|LINK
I was trying to apply AsyncTimeout attribute on my Async aciton of a Async controller. It looks like not able to produce a TimeoutException. Does anyone know how to use this attribute?
Here is my sample code for testing this attribute:
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(); } } }http://blog.miniasp.com/
levib
Star
7702 Points
1099 Posts
Microsoft
Re: The AsyncTimeout filter doesn't works
Jun 01, 2010 07:13 PM|LINK
The [AsyncTimeout] attribute controls the maximum time to wait when the XxAsync() method kicks off an async operation, like making a network request. The timer doesn't start until the IndexAsync() method returns. Since Thread.Sleep() is a synchronous operation, it blocks IndexAsync() from returning in your example.
Doggy8088
Member
41 Points
110 Posts
Re: The AsyncTimeout filter doesn't works
Jun 02, 2010 02:11 AM|LINK
This isn't what I expected. I was expected AsyncController's AsyncAction as an independent thread to run code. So I have to use Async model to write code in my AsyncController, right?
Thanks!
http://blog.miniasp.com/
imran_ku07
All-Star
45864 Points
7713 Posts
MVP
Re: The AsyncTimeout filter doesn't works
Jun 02, 2010 02:28 AM|LINK
AFAIK that action executing the code is asynchronous,
As given in Microsoft MVC Book,
I think AsyncTimeout is expressed in milliseconds not in seconds
You can check the current thread property to find that which thread is executing,
Thread.CurrentThread.IsThreadPoolThread
Thread.CurrentThread.Name
etc..
Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD
levib
Star
7702 Points
1099 Posts
Microsoft
Re: The AsyncTimeout filter doesn't works
Jun 02, 2010 04:32 AM|LINK
Documentation for the AsyncController can be found at http://msdn.microsoft.com/en-us/library/ee728598.aspx. In particular, look at the diagram under the Processing Asynchronous Requests section. The XxAsync() method executes on Thread A; the XxCompleted() method executes on Thread B. The XxAsync() / XxCompleted() method pair constitutes a single logical "action method", which is why the dashed line in the diagram goes through the block marked "action method". Note that Thread A and Thread B might actually be the same thread.
The [AsyncTimeout] attribute affects only that dashed line. The attribute says "if the asynchronous action method has not completed within a set amount of time, fail the request." But note that since the attribute affects the dashed line and that the dashed line occurs between XxAsync() and XxCompleted(), the timer does not start until after the XxAsync() method returns.
This might seem counterintuitive but actually makes sense. Consider what would happen if the timer were to start before the XxAsync() method executes. 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. 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.
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.
imran_ku07
All-Star
45864 Points
7713 Posts
MVP
Re: The AsyncTimeout filter doesn't works
Jun 02, 2010 05:50 PM|LINK
Is you check Thread.CurrentThread properties in both XxAsync() and XxCompleted(), like
Thread.CurrentThread.IsThreadPoolThread
Thread.CurrentThread.Name etc
Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD
imran_ku07
All-Star
45864 Points
7713 Posts
MVP
Re: The AsyncTimeout filter doesn't works
Jun 12, 2010 01:15 PM|LINK
After my checking i found that the thread is same both in Application_Start and XxAsync.
Here is the proof,
public ActionResult Index()
{
Debug.WriteLine("Index"+AppDomain.GetCurrentThreadId().ToString());
}
protected void Application_BeginRequest()
{
Debug.WriteLine("Begin" + AppDomain.GetCurrentThreadId().ToString());
}
I was confused from the Microsoft Dino's book example,
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
Thanks you also for the link. I appreciate the Rick article and Rick example.
Now We can say that XxAsync is synchronous but the method it starts from XxAsync using Begin/End pattern is asynchronous.
What do you say Levib?
Also can you tell me how ASP.NET knows that XxAsync starts asynchrnous task/tasks?
Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD
levib
Star
7702 Points
1099 Posts
Microsoft
Re: The AsyncTimeout filter doesn't works
Jun 14, 2010 05:44 PM|LINK
Correct. Generally Decrement() shouldn't be called from the XxAsync() method, though there are some rare exceptions. I'm not familiar with the example you posted, though, so I can't really comment on it without the full context.
This is true in a sense, just like if you call a BeginXx / EndXx method (like Stream.BeginRead(), EndRead()). The methods are themselves synchronous, and nothing else can happen on the thread on which they're executing until the methods return. Their jobs are to kick off an asynchronous task (BeginRead) or retrieve and join the results of an asynchronous task (EndRead).
It doesn't, hence the Increment() / Decrement() counters are necessary.
imran_ku07
All-Star
45864 Points
7713 Posts
MVP
Re: The AsyncTimeout filter doesn't works
Jun 14, 2010 05:56 PM|LINK
Thank you very much for your reply and time.
Now, we can say that XXCompleted is called when OutstandingOperations is become 0?
The example posted from this book,
http://www.microsoft.com/learning/en/us/Books.aspx?Id=13989&locale=en-us
Excellent Windows VPS Hosting
Imran Baloch MVP, MVB, MCP, MCTS, MCPD