|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Async web calls can't be timed?I'm making few asynchronous web requests (loop) using System.Net namespace with HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. The asynchronous part works, but I also want to time my requests. That part does not work. Someone suggested this: ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), requestState, (4 * 1000), true); The above line times all my calls as one. I want to be able to time every request individually and if one of them is timing out, abort that one only. There are no examples for this anywhere. How do you time each individual request on a specific thread. Thanks in advance, Hello,
well, with each call to BeginXXX, you get a unique IAsyncResult. And thus, you can register each IAsyncResult.AsyncWaitHandle with ThreadPool.RegisterWaitForSingleObject). Where exactly is the problem here? Best regards, Henning Krause Show quote "Andy" <A***@discussions.microsoft.com> wrote in message news:CB4C1CF3-E7ED-4077-A93A-F5092F3E4B79@microsoft.com... > Tough asynchronous web request question. > > I'm making few asynchronous web requests (loop) using System.Net namespace > with > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. > > The asynchronous part works, but I also want to time my requests. That > part > does not work. > Someone suggested this: > > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (4 * 1000), true); > > The above line times all my calls as one. I want to be able to time every > request individually and if one of them is timing out, abort that one > only. > There are no examples for this anywhere. How do you time each individual > request on a specific thread. > > Thanks in advance, > >
Show quote
"Henning Krause [MVP - Exchange]" wrote: This is what I do:> Hello, > > well, with each call to BeginXXX, you get a unique IAsyncResult. And thus, > you can register each IAsyncResult.AsyncWaitHandle with > ThreadPool.RegisterWaitForSingleObject). > > Where exactly is the problem here? > > Best regards, > Henning Krause > > > "Andy" <A***@discussions.microsoft.com> wrote in message > news:CB4C1CF3-E7ED-4077-A93A-F5092F3E4B79@microsoft.com... > > Tough asynchronous web request question. > > > > I'm making few asynchronous web requests (loop) using System.Net namespace > > with > > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. > > > > The asynchronous part works, but I also want to time my requests. That > > part > > does not work. > > Someone suggested this: > > > > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (4 * 1000), true); > > > > The above line times all my calls as one. I want to be able to time every > > request individually and if one of them is timing out, abort that one > > only. > > There are no examples for this anywhere. How do you time each individual > > request on a specific thread. > > > > Thanks in advance, > > > > > > foreach(Uri uri in arrayList) { request = (HttpWebRequest)WebRequest.Create(uri); request.Method = "GET"; data = new object(); RequestState requestState = new RequestState(request, data, uri); asyncResult = request.BeginGetResponse(new AsyncCallback(ProcessRequest), requestState); ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(ScanTimeoutCallback), requestState, (30 * 1000), true); } This should create a timer call back for each request, but it does not. It basically times all the requests together. For example: if by the 3rd request the timer is at 30 sec it times out. I want every request to run for 30 sec max and time out as oppose to run till the timeout expires for all. Hmm... should work this way.
But I usually only use one callback: asyncResult = request.BeginGetResponse(new null, null); RequestState requestState = new RequestState(request, data, uri, asyncResult); ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new WaitOrTimerCallback(ProcessRequest), requestState, (30 * 1000), true); private void ProcessRequest(object state, bool timedOut) { RequestState data = state as RequestState; if (timedOut) { // Handle timeout data.Request.Abort(); } else { HttpWebResponse response = data.Request.EndGetResponse(data.AsyncResult); ProcessResponse(response); } } Best regards, Henning Krause Show quote "Andy" <A***@discussions.microsoft.com> wrote in message news:7CF9C1E2-3CB8-44A3-83C2-E579577E0DCC@microsoft.com... > > > "Henning Krause [MVP - Exchange]" wrote: > >> Hello, >> >> well, with each call to BeginXXX, you get a unique IAsyncResult. And >> thus, >> you can register each IAsyncResult.AsyncWaitHandle with >> ThreadPool.RegisterWaitForSingleObject). >> >> Where exactly is the problem here? >> >> Best regards, >> Henning Krause >> >> >> "Andy" <A***@discussions.microsoft.com> wrote in message >> news:CB4C1CF3-E7ED-4077-A93A-F5092F3E4B79@microsoft.com... >> > Tough asynchronous web request question. >> > >> > I'm making few asynchronous web requests (loop) using System.Net >> > namespace >> > with >> > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. >> > >> > The asynchronous part works, but I also want to time my requests. That >> > part >> > does not work. >> > Someone suggested this: >> > >> > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new >> > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (4 * 1000), >> > true); >> > >> > The above line times all my calls as one. I want to be able to time >> > every >> > request individually and if one of them is timing out, abort that one >> > only. >> > There are no examples for this anywhere. How do you time each >> > individual >> > request on a specific thread. >> > >> > Thanks in advance, >> > >> > >> >> > > This is what I do: > > foreach(Uri uri in arrayList) > { > request = (HttpWebRequest)WebRequest.Create(uri); > request.Method = "GET"; > > data = new object(); > > RequestState requestState = new RequestState(request, data, uri); > asyncResult = request.BeginGetResponse(new > AsyncCallback(ProcessRequest), requestState); > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (30 * 1000), > true); > } > > This should create a timer call back for each request, but it does not. > It > basically times all the requests together. For example: if by the 3rd > request the timer is at 30 sec it times out. I want every request to run > for > 30 sec max and time out as oppose to run till the timeout expires for all.
Show quote
"Henning Krause [MVP - Exchange]" wrote:
> Hmm... should work this way. > > But I usually only use one callback: > > asyncResult = request.BeginGetResponse(new > null, null); > RequestState requestState = new RequestState(request, data, uri, > asyncResult); > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > WaitOrTimerCallback(ProcessRequest), requestState, (30 * 1000), true); > > private void ProcessRequest(object state, bool timedOut) { > RequestState data = state as RequestState; > > if (timedOut) { > // Handle timeout > data.Request.Abort(); > } > else { > HttpWebResponse response = > data.Request.EndGetResponse(data.AsyncResult); > > ProcessResponse(response); > } > > } > > Best regards, > Henning Krause > > > "Andy" <A***@discussions.microsoft.com> wrote in message > news:7CF9C1E2-3CB8-44A3-83C2-E579577E0DCC@microsoft.com... > > > > > > "Henning Krause [MVP - Exchange]" wrote: > > > >> Hello, > >> > >> well, with each call to BeginXXX, you get a unique IAsyncResult. And > >> thus, > >> you can register each IAsyncResult.AsyncWaitHandle with > >> ThreadPool.RegisterWaitForSingleObject). > >> > >> Where exactly is the problem here? > >> > >> Best regards, > >> Henning Krause > >> > >> > >> "Andy" <A***@discussions.microsoft.com> wrote in message > >> news:CB4C1CF3-E7ED-4077-A93A-F5092F3E4B79@microsoft.com... > >> > Tough asynchronous web request question. > >> > > >> > I'm making few asynchronous web requests (loop) using System.Net > >> > namespace > >> > with > >> > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. > >> > > >> > The asynchronous part works, but I also want to time my requests. That > >> > part > >> > does not work. > >> > Someone suggested this: > >> > > >> > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > >> > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (4 * 1000), > >> > true); > >> > > >> > The above line times all my calls as one. I want to be able to time > >> > every > >> > request individually and if one of them is timing out, abort that one > >> > only. > >> > There are no examples for this anywhere. How do you time each > >> > individual > >> > request on a specific thread. > >> > > >> > Thanks in advance, > >> > > >> > > >> > >> > > > > This is what I do: > > > > foreach(Uri uri in arrayList) > > { > > request = (HttpWebRequest)WebRequest.Create(uri); > > request.Method = "GET"; > > > > data = new object(); > > > > RequestState requestState = new RequestState(request, data, uri); > > asyncResult = request.BeginGetResponse(new > > AsyncCallback(ProcessRequest), requestState); > > ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, new > > WaitOrTimerCallback(ScanTimeoutCallback), requestState, (30 * 1000), > > true); > > } > > > > This should create a timer call back for each request, but it does not. > > It > > basically times all the requests together. For example: if by the 3rd > > request the timer is at 30 sec it times out. I want every request to run > > for > > 30 sec max and time out as oppose to run till the timeout expires for all. > > Well if you use one call only it is obvious it times only that call. Try adding more than one call. The timer spans across all threads and times them as a whole. "Andy" <A***@discussions.microsoft.com> wrote I would grab the current system time (DateTime.Now), and just pass that in > > I'm making few asynchronous web requests (loop) using System.Net namespace > with > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. > > The asynchronous part works, but I also want to time my requests. as state to the async call. When you get your callback, you can then (inside the callback) access your original start time by saying "DateTime startTime = ar.AsyncState as DateTime;" From here, it's easy enough to calculate a start date.
Show quote
"Chris Mullins [MVP]" wrote: Hm.. So wait, you are saying I can set the time in the state object and pass > "Andy" <A***@discussions.microsoft.com> wrote > > > > I'm making few asynchronous web requests (loop) using System.Net namespace > > with > > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. > > > > The asynchronous part works, but I also want to time my requests. > > I would grab the current system time (DateTime.Now), and just pass that in > as state to the async call. > > When you get your callback, you can then (inside the callback) access your > original start time by saying > "DateTime startTime = ar.AsyncState as DateTime;" > > From here, it's easy enough to calculate a start date. > > -- > Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C# > http://www.coversant.net/blogs/cmullins > > > it to my call. When the callback gets triggered I can check the time again and see the difference. That's great, but I wanted to set a timeout. I did not want to time the call only. I see your point, but that's half the equation. How do I call a callback from the async call if the async call is taking more than 10 sec for example. And the problem here is, that async calls don't automatically timeout, as
synchronous do... So, the call can take forever to complete... Best regards, Henning Krause Show quote "Andy" <A***@discussions.microsoft.com> wrote in message news:4985AF61-01C5-48B6-8A04-D178F1DFC707@microsoft.com... > > > "Chris Mullins [MVP]" wrote: > >> "Andy" <A***@discussions.microsoft.com> wrote >> > >> > I'm making few asynchronous web requests (loop) using System.Net >> > namespace >> > with >> > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. >> > >> > The asynchronous part works, but I also want to time my requests. >> >> I would grab the current system time (DateTime.Now), and just pass that >> in >> as state to the async call. >> >> When you get your callback, you can then (inside the callback) access >> your >> original start time by saying >> "DateTime startTime = ar.AsyncState as DateTime;" >> >> From here, it's easy enough to calculate a start date. >> >> -- >> Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C# >> http://www.coversant.net/blogs/cmullins >> >> >> > Hm.. So wait, you are saying I can set the time in the state object and > pass > it to my call. When the callback gets triggered I can check the time > again > and see the difference. That's great, but I wanted to set a timeout. I > did > not want to time the call only. I see your point, but that's half the > equation. How do I call a callback from the async call if the async call > is > taking more than 10 sec for example. You really can't have the async calls timeout, unfortunatly.
I agree with you that this isn't exactly ideal. In general, to abort an async operation, you've got to dispose the object the operation is occuring on. For example, to abort a socket.BeginRead call, I've got to dispose the socket. As soon as that socket it disposed, my callback will fire, call EndRead, and pickup that the socket has been closed. Show quote "Andy" <A***@discussions.microsoft.com> wrote in message news:4985AF61-01C5-48B6-8A04-D178F1DFC707@microsoft.com... > > > "Chris Mullins [MVP]" wrote: > >> "Andy" <A***@discussions.microsoft.com> wrote >> > >> > I'm making few asynchronous web requests (loop) using System.Net >> > namespace >> > with >> > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. >> > >> > The asynchronous part works, but I also want to time my requests. >> >> I would grab the current system time (DateTime.Now), and just pass that >> in >> as state to the async call. >> >> When you get your callback, you can then (inside the callback) access >> your >> original start time by saying >> "DateTime startTime = ar.AsyncState as DateTime;" >> >> From here, it's easy enough to calculate a start date. >> >> -- >> Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C# >> http://www.coversant.net/blogs/cmullins >> >> >> > Hm.. So wait, you are saying I can set the time in the state object and > pass > it to my call. When the callback gets triggered I can check the time > again > and see the difference. That's great, but I wanted to set a timeout. I > did > not want to time the call only. I see your point, but that's half the > equation. How do I call a callback from the async call if the async call > is > taking more than 10 sec for example. Well,
the HttpWebRequest class has an Abort method.. Best regards, Henning Krause Show quote "Chris Mullins [MVP]" <cmull***@yahoo.com> wrote in message news:ugyzq8BMHHA.4848@TK2MSFTNGP04.phx.gbl... > You really can't have the async calls timeout, unfortunatly. > > I agree with you that this isn't exactly ideal. In general, to abort an > async operation, you've got to dispose the object the operation is > occuring on. > > For example, to abort a socket.BeginRead call, I've got to dispose the > socket. As soon as that socket it disposed, my callback will fire, call > EndRead, and pickup that the socket has been closed. > > -- > Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C# > http://www.coversant.net/blogs/cmullins > > "Andy" <A***@discussions.microsoft.com> wrote in message > news:4985AF61-01C5-48B6-8A04-D178F1DFC707@microsoft.com... >> >> >> "Chris Mullins [MVP]" wrote: >> >>> "Andy" <A***@discussions.microsoft.com> wrote >>> > >>> > I'm making few asynchronous web requests (loop) using System.Net >>> > namespace >>> > with >>> > HttpWebRequest, BeginGetRespons, AsyncCallback and all that stuff. >>> > >>> > The asynchronous part works, but I also want to time my requests. >>> >>> I would grab the current system time (DateTime.Now), and just pass that >>> in >>> as state to the async call. >>> >>> When you get your callback, you can then (inside the callback) access >>> your >>> original start time by saying >>> "DateTime startTime = ar.AsyncState as DateTime;" >>> >>> From here, it's easy enough to calculate a start date. >>> >>> -- >>> Chris Mullins, MCSD.NET, MCPD:Enterprise, MVP C# >>> http://www.coversant.net/blogs/cmullins >>> >>> >>> >> Hm.. So wait, you are saying I can set the time in the state object and >> pass >> it to my call. When the callback gets triggered I can check the time >> again >> and see the difference. That's great, but I wanted to set a timeout. I >> did >> not want to time the call only. I see your point, but that's half the >> equation. How do I call a callback from the async call if the async call >> is >> taking more than 10 sec for example. > > |
|||||||||||||||||||||||