async pages and redirect

G

Guest

I am having trouble doing a redirect in an async asp.net implemention.
Most of the time it works, but when it doesn't it just "hangs", the browser
never gets any return page. If I run it under the debugger, it works fine,
though every so often I get a HttpException.

System.Web.HttpException was caught
ErrorCode=-2147024809
Message="An error occurred while communicating with the remote host. The
error code is 0x80070057."
Source="System.Web"
StackTrace:
at
System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.FlushCore(Byte[] status,
Byte[] header, Int32 keepConnected, Int32 totalBodySize, Int32
numBodyFragments, IntPtr[] bodyFragments, Int32[] bodyFragmentLengths, Int32
doneWithSession, Int32 finalStatus, Boolean& async)
at System.Web.Hosting.ISAPIWorkerRequest.FlushCachedResponse(Boolean
isFinal)
at System.Web.Hosting.ISAPIWorkerRequest.FlushResponse(Boolean
finalFlush)
at System.Web.HttpResponse.Flush(Boolean finalFlush)
at System.Web.HttpResponse.Flush()
at System.Web.HttpResponse.End()
at System.Web.HttpResponse.Redirect(String url, Boolean endResponse)
at w2pagev.PageV.EndPage(IAsyncResult ar) in
G:\inetpub\wwwroot\w2pagev\page.aspx.vb:line 100

The exception is caught in the EndEventHandler.
I am using AddOnPreRenderCompleteAsync to set this up.
 
S

Steven Cheng[MSFT]

Hello Pb,

Based on your description, you have an ASP.NET page that is configured as
async execution and it works for most time but will occasionally raise some
error as below, correct?System.Web.HttpException was caught
ErrorCode=-2147024809
Message="An error occurred while communicating with the remote host. The
error code is 0x80070057."
<<<<<<<<<<<<<<<<<<<

So far as I've researched, there hasn't any definite issue of the ASP.NET
2.0 Async page execution. I think the problem here should be application
code logic specific. Would you provide some code logic of your problem
async page, such as what you've done in the async handler, and when you
call the response.Redirect. If possible, you can try simplified it to the
code that is necessary to repro the problem.

In addition, have you checked whether the problem occurs at high stress
condition, such as the application has been stressed under high volume
request execution or will occur even if there is few concurrent requests?

Anyway, please feel free to let me know if you have any other finding or
anything I've missed on this

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Steven Cheng said:
Hello Pb,

Based on your description, you have an ASP.NET page that is configured as
async execution and it works for most time but will occasionally raise some
error as below, correct?System.Web.HttpException was caught
ErrorCode=-2147024809
Message="An error occurred while communicating with the remote host. The
error code is 0x80070057."
<<<<<<<<<<<<<<<<<<<

So far as I've researched, there hasn't any definite issue of the ASP.NET
2.0 Async page execution. I think the problem here should be application
code logic specific. Would you provide some code logic of your problem
async page, such as what you've done in the async handler, and when you
call the response.Redirect. If possible, you can try simplified it to the
code that is necessary to repro the problem.

In addition, have you checked whether the problem occurs at high stress
condition, such as the application has been stressed under high volume
request execution or will occur even if there is few concurrent requests?

Anyway, please feel free to let me know if you have any other finding or
anything I've missed on this

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================



This posting is provided "AS IS" with no warranties, and confers no rights.


I may have solved my problem, but it’s hard to know with intermittent
problems like this… so let me better describe it:

The async model is hooked up like this:


Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim bh As New BeginEventHandler(AddressOf Me.BeginPage)
Dim eh As New EndEventHandler(AddressOf Me.EndPage)
Me.AddOnPreRenderCompleteAsync(bh, eh)
End Sub


Function BeginPage(ByVal src As Object, ByVal args As EventArgs, ByVal cb As
AsyncCallback, ByVal state As Object) As IAsyncResult

Trace.Write("BeginPage: Thread #" &
System.Threading.Thread.CurrentThread.GetHashCode() & "; " &
System.Threading.Thread.CurrentThread.IsThreadPoolThread)

Dim v As New vmstate
v.m_page = Me
v.m_config = m_config

Dim vrs As New viewmanagerstate(Context, cb, v)
m_vm = New viewmanager(vrs)
Dim ts As New ThreadStart(AddressOf m_vm.start)
Dim thread As New Thread(ts)
thread.Start()

Return vrs
End Function

Sub EndPage(ByVal ar As IAsyncResult)

Try
Trace.Write("EndPage: Thread #" &
System.Threading.Thread.CurrentThread.GetHashCode() & "; " &
System.Threading.Thread.CurrentThread.IsThreadPoolThread)

Dim m_vrs As viewmanagerstate = CType(ar, viewmanagerstate)
If Not IsNothing(m_vrs.m_data.m_redirect) Then
m_redirect = m_vrs.m_data.m_redirect
'Response.Redirect(m_vrs.m_data.m_redirect, True)
End If
Catch ex As Exception
End Try
End Sub


Protected Overrides Sub OnPreRenderComplete(ByVal e As System.EventArgs)
MyBase.OnPreRenderComplete(e)

Try
Trace.Write("OnPreRenderComplete: Thread #" &
System.Threading.Thread.CurrentThread.GetHashCode() & "; " &
System.Threading.Thread.CurrentThread.IsThreadPoolThread)

If Not IsNothing(m_redirect) Then
Response.Redirect(m_redirect, True)
End If
Catch ex As Exception
End Try
End Sub

For now, I left out the details of viewmanagerstate, but it is a class that
implements IAsyncResult.

So in begin, I spin off a new thread. This is NOT a thread pool thread
(which of course is the whole point).

So the trouble occurs if I use Response.Redirect from EndPage. This will be
in my new thread’s context and perhaps that’s the problem right there, the
Response.Redirect with TRUE will abort the thread (I think). After posting,
I moved the Redirect to OnPreRenderComplete, where we are back on a thread
pool thread.

It seems to work there; I have tested it and can’t get it to break as
before, but I am concerned that the problem is just less likely in this
context vs. fixed. It would be great to confirm from MSFT that the
Response.Redirect in EndPage will not work and moving it to
OnPreRenderComplete is the way to go.

I can provide more details of my implementation if it would help.
 
J

John Saunders

pb said:
:
The async model is hooked up like this:


Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim bh As New BeginEventHandler(AddressOf Me.BeginPage)
Dim eh As New EndEventHandler(AddressOf Me.EndPage)
Me.AddOnPreRenderCompleteAsync(bh, eh)
End Sub


Function BeginPage(ByVal src As Object, ByVal args As EventArgs, ByVal cb
As
AsyncCallback, ByVal state As Object) As IAsyncResult

Trace.Write("BeginPage: Thread #" &
System.Threading.Thread.CurrentThread.GetHashCode() & "; " &
System.Threading.Thread.CurrentThread.IsThreadPoolThread)

Dim v As New vmstate
v.m_page = Me
v.m_config = m_config

Dim vrs As New viewmanagerstate(Context, cb, v)
m_vm = New viewmanager(vrs)
Dim ts As New ThreadStart(AddressOf m_vm.start)
Dim thread As New Thread(ts)
thread.Start()

Maybe it's in the code you didn't include, but I don't see what keeps your
page from completing the request before your thread even begins executing.
This will cause your thread to be referenceing a page which is in an invalid
state. Perhaps it's your thread that caused the EndPage to be called?

You are creating a major maintenance headache for yourself with this code.
There is a reason why you don't see many examples of ASP.NET code that
creates another thread. It's not meant to work that way.

John
 
G

Guest

John Saunders said:
Maybe it's in the code you didn't include, but I don't see what keeps your
page from completing the request before your thread even begins executing.
This will cause your thread to be referenceing a page which is in an invalid
state. Perhaps it's your thread that caused the EndPage to be called?

You are creating a major maintenance headache for yourself with this code.
There is a reason why you don't see many examples of ASP.NET code that
creates another thread. It's not meant to work that way.

John

John,

thanks for the reply, but i don't understand your points.
AddOnPreRenderCompleteAsync is setup by MSFT for async pages. ASP.NET keeps
the page from completing by ensuring BeginPage is called in the chain. then,
yes, my thread callsback to EndPage.

there is no reason i can't spin up a thread here. see
http://msdn.microsoft.com/msdnmag/issues/05/10/WickedCode/ for more
information.
 
S

Steven Cheng[MSFT]

Thanks for your followup Pb,

After got the code snippet you provided, I notice that your implementation
is quite different as I expect. Yes, you haven't simply used the existing
async components (like delegate or WebRequest...) and manually create a
normal sub thread to do the work.

And in addition to the "IAsyncResult" implmentation class, another thing
you haven't provided is your thread proc function. You need to ensure the
passed in callback should be invoked at the end of your thread proc
function(when the task has finished). Also, I think the occasional hang
problem does be possible related to the IAsyncResult implementation. You
can try using Delegate.BeginInvoke approach to run the same stuff to see
whether it will lead to the same behvior.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Steven Cheng said:
Thanks for your followup Pb,

After got the code snippet you provided, I notice that your implementation
is quite different as I expect. Yes, you haven't simply used the existing
async components (like delegate or WebRequest...) and manually create a
normal sub thread to do the work.

And in addition to the "IAsyncResult" implmentation class, another thing
you haven't provided is your thread proc function. You need to ensure the
passed in callback should be invoked at the end of your thread proc
function(when the task has finished). Also, I think the occasional hang
problem does be possible related to the IAsyncResult implementation. You
can try using Delegate.BeginInvoke approach to run the same stuff to see
whether it will lead to the same behvior.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.

Steven-

a couple of things... i don't think i am having any more trouble with the
redirect now that i've moved it (see previous code). i do, however,
experience "hangs" when running the new thread model under load (using WCAT).
over the course of several hours, i will see ASP.NET restart several times
when it failed to respond to the IIS ping. i do not experience these hangs
when i switch to my old implementation (i have a simple switch that runs it
async or not).

i too suspect it might be the iasyncresult implemention, and i will test
under a simple async delegate model to try to isolate it. in the mean time,
here is my iasynresult implementation:


Public Class viewmanagerstate
Implements IAsyncResult

Public m_context As HttpContext
Public m_cb As AsyncCallback
Public m_data As vmstate
Public m_iscompleted As Boolean = False
Public m_callcompleteevent As ManualResetEvent = Nothing

Public Sub New(ByVal context As HttpContext, ByVal cb As AsyncCallback,
ByVal data As Object)

m_context = context
m_cb = cb
m_data = data
End Sub

Public ReadOnly Property AsyncState() As Object Implements
System.IAsyncResult.AsyncState
Get
Return m_data
End Get
End Property

Public ReadOnly Property AsyncWaitHandle() As
System.Threading.WaitHandle Implements System.IAsyncResult.AsyncWaitHandle
Get
SyncLock Me
If IsNothing(m_callcompleteevent) Then
m_callcompleteevent = New ManualResetEvent(False)
End If
End SyncLock

Return m_callcompleteevent
End Get
End Property

Public ReadOnly Property CompletedSynchronously() As Boolean Implements
System.IAsyncResult.CompletedSynchronously
Get
Return False
End Get
End Property

Public ReadOnly Property IsCompleted() As Boolean Implements
System.IAsyncResult.IsCompleted
Get
Return m_iscompleted
End Get
End Property

Public Sub CompleteRequest()

m_iscompleted = True

SyncLock Me
If Not IsNothing(m_callcompleteevent) Then
m_callcompleteevent.Set()
End If
End SyncLock

m_cb.Invoke(Me)
End Sub
End Class
 
J

John Saunders

pb said:
....



John,

thanks for the reply, but i don't understand your points.
AddOnPreRenderCompleteAsync is setup by MSFT for async pages. ASP.NET
keeps
the page from completing by ensuring BeginPage is called in the chain.
then,
yes, my thread callsback to EndPage.

As I said above, "maybe it's in the code you didn't include". If the
completion of your thread is the only way for EndPage to be called, then you
won't have the issue I was concerned with, as the page will not complete
before your thread is through with it.

In general, this technique should work, at least until you can no longer
create new threads.

John
 
J

John Saunders

pb said:
Steven-

a couple of things... i don't think i am having any more trouble with the
redirect now that i've moved it (see previous code). i do, however,
experience "hangs" when running the new thread model under load (using
WCAT).
over the course of several hours, i will see ASP.NET restart several times
when it failed to respond to the IIS ping. i do not experience these hangs
when i switch to my old implementation (i have a simple switch that runs
it
async or not).


Make very certain that you have a try/catch block around all of your
threads. Otherwise, an unhandled exception will just quietly kill the
thread.

John
 
G

Guest

Steven Cheng said:
Thanks for your followup Pb,

After got the code snippet you provided, I notice that your implementation
is quite different as I expect. Yes, you haven't simply used the existing
async components (like delegate or WebRequest...) and manually create a
normal sub thread to do the work.

And in addition to the "IAsyncResult" implmentation class, another thing
you haven't provided is your thread proc function. You need to ensure the
passed in callback should be invoked at the end of your thread proc
function(when the task has finished). Also, I think the occasional hang
problem does be possible related to the IAsyncResult implementation. You
can try using Delegate.BeginInvoke approach to run the same stuff to see
whether it will lead to the same behvior.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.

Steven--

at your suggestion, i tried a simple async delegate model. it works; i ran
it through an overnight test and ASP.NET never restarted. so i pretty much
believe that its either my iasyncresult implementation or under my
iasyncresult implementation the code is stressed in another way that causes
it to break. if you could look over my iasyncresult implementation, it would
be much appreciated (its in the previous post).

/phil
 
P

phil

Make very certain that you have a try/catch block around all of your
threads. Otherwise, an unhandled exception will just quietly kill the
thread.

John- Hide quoted text -

- Show quoted text -

john,

that's an important point. if an exception aborts the thread before
it completes EndPage won't be called. what does ASP.NET do in that
case? does it just time out the initial thread that dispatched the
page (the CLR thread pool thread)? i imagine, even if it timed out
the dispatch thread that all the thread pool threads could be consumed
in this case and then ASP.NET would "hang"... and IIS would be forced
to restart it. i will make certain my thread always completes to the
caller regardless of what is does in between!

/phil
 
S

Steven Cheng[MSFT]

Thanks for your reply Pb,

I'll have a further check and test based on the code you provided. I'll
update you as soon as possible.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
S

Steven Cheng[MSFT]

Hi Pb,

Sorry for the dely update. After some further research, I still haven't
been able to address the root cause of the issue. The difficulty here is
that the behavior is quite hard to test in development, and the underlying
cause require some low level debugging. After discussing with some other
engineers, we suggest you consider contact CSS for further troubleshooting
on this issue:

http://msdn.microsoft.com/subscriptions/support/default.aspx

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top