| « Static classes in C# and Java | Bing app with Navigation for Windows Mobile released! » |
HttpWebRequest.Abort() in .NET Compact Framework 2 doesn't work when m_connection is null
Wednesday, March 31, 2010
Note: This post applies to CF 2.0 and below. It is fixed in later versions.
I literally spent days poring over our app's code to figure out what was going wrong. Eventually I gave up and blamed our failure on the Compact Framework code, and it seems I was correct. It appears that in CF 2.0, HttpWebRequest.Abort() is broken in some cases and causes very difficult-to-detect incorrectness in subsequent requests.
Create and send an HttpWebRequest:
HttpWebRequest r = (HttpWebRequest)WebRequest.Create("http://www.example.com/");
r.BeginGetResponse(new AsyncCallback(SomeFunction), null);
Now, sometime later but before the request is completed, try to abort the request:
r.Abort();
It's obvious what this code is supposed to do, and the API also clearly states what is supposed to happen — the request is cancelled. However, due to a CF bug, that doesn't always work correctly.
If you Abort() the request early enough, it is possible that the m_connection private member of the HttpWebRequest object has not been set. In this case, the Abort() call actually fails to abort the connection. In fact, the HttpWebRequest will appear to have been aborted, but its underlying Connection object (and its Socket object) will still be sitting around. Since the Connection objects used by HttpWebRequest are pooled, this is very bad. It leaves the Connection object in an unaborted state while its owning HttpWebRequest has been aborted — meaning when the Connection object is reused by a different request, it still has old state and will behave in unexpected ways.
Consider the following scenario:
- Client creates a new
HttpWebRequestand begins a request for HTTP resource A. - Someone calls
Abort()on that request beforem_connectionis set. - Abort will silently fail and the underlying
ConnectionandSocketwill be left in an invalid state. - Client creates a new
HttpWebRequestand begins a request for HTTP resource B. - Since
HttpWebRequests are not pooled,HttpWebRequestB is a different object from the now-defunctHttpWebRequestA. However, their underlyingConnectionobjects are pooled.HttpWebRequestB tries to get aConnectionfrom the pool, and may end up with theConnectionthat A left in an invalid state. HttpWebRequestB sends things through its underlyingConnectionand theSocketowned by theConnection. But theSocketis still connected to resource A.HttpWebRequestB thinks it successfully sent request B. The server returns content from A since that's what theSocket's associated with.HttpWebRequestB gets a response stream from the server. It thinks that this contains data from resource B, when in fact it is data from resource A.
So you end up with random data corruption. Not only that, but it's silent: it's very difficult to detect this condition, and most of the time the data looks legitimate. For example if you're downloading 100 images and image #50 actually contains the data that was supposed to go into image #49, well, tough luck because it looks like a legitimate image.
I spent forever trying to come up with solutions to this, but could only come up with ones that don't work:
Do not call
Abort()onHttpWebRequests whosem_connectionmember is null.Since this bug occurs iff
m_connection == nullwhen aborting, if we avoid doing that then this bug can never occur. The problem is thatAbort()is the only way to kill the request, and it may not be possible for your app to completely avoid aborting requests. In addition, since theConnectionobjects are pooled and there are very few of them in the pool, you can't leave these requests hanging around or your app will quickly run out of connections. (IfAbort()is called and this bug is triggered, theConnectionwill be returned to the pool and not block subsequent requests; it will just have unpredictable behavior next time.)When aborting, check
m_connection, and if it's null then store theConnectionwhich is about to become invalid into a data structure somewhere. When anHttpWebRequestreturns data, check to see whether it came from a brokenConnection; if so disregard the data and retry.This would work... if it was possible to get the
HttpWebRequest'sConnectionobject. But since the bug only occurs whenm_connection == null, and because theConnectionis actually created deep within the innards of the code, passed around as a local variable, and is not known to theHttpWebRequestuntil a callback some time later, it's not possible at abort time to get a reference to theConnectionobject, not even with reflection.Also, since the
HttpWebRequestaren't pooled, keeping track of those is not useful.Inherit from
HttpWebRequest. Tag each one with a unique ID, and when the response comes back check to see the ID is what you expectSince
HttpWebRequests aren't pooled this doesn't work. It's the underlyingConnectionwhich is pooled and left in an invalid state, not the request itself.Set a timeout on the underlying
Connectionor theSocketthat it owns so they can dispose themselves.Those two objects don't have such a thing as timeouts, at least not in CF, and even if they did there's no way to get a reference to those objects until
m_connectionis set (but the bug is gone by that point).HttpWebRequesthas a timeout but it is useless as it simply callsAbort()when the timer rings, so will still exhibit the buggy behavior.
The fix is to use CF 3.5, but I have to support 2.0. Still looking for a workaround...
Comments
Almeda Donahue on Tuesday, June 16, 2026 at 03:22
Our AI-driven service delivers keyword and location-specific visitors to your site, offering significant savings over paid ads. Connect with us today.
https://marketingaged.com/
Leticia Thompson on Thursday, June 18, 2026 at 18:13
Drive targeted traffic to your website with our AI-powered solution, costing far less than expensive paid advertising. Connect with us to boost your results.
https://marketingaged.com/
JamesSmurl on Friday, June 19, 2026 at 15:38
Делюсь моментами, эмоциями и вдохновением. Здесь тренды, лайфстайл и немного моей жизни. Подписывайся, чтобы не пропустить самое интересное! ???? #fyp #viral #tiktok<a href=https://t.me/slon9atsite/4>как войти в даркнет ru2tor com
</a>
Ricky Kunkle on Saturday, June 20, 2026 at 13:19
Professional video content is one of the fastest ways to make your business website stand out and convert better. We handle the heavy lifting—check out this sample:
https://www.youtube.com/shorts/SglkEN-n7_U
CarlosShoor on Sunday, June 21, 2026 at 22:11
Jailbreak is a daring escape from digital confinement. Bypassing security, it grants freedom to restricted systems. Risky yet thrilling, it challenges norms and boundaries. Like a digital heist, it requires skill and precision. Freedom comes with responsibility, as consequences may follow. <a href=https://google.hn/url?q=http://53o7o7gqt2oy67ufgm3mutefrrx3gllu4oe3ds7e4k3wny32yasqaoqd.onion>jailbailt & teen
</a>
CarlosShoor on Monday, June 22, 2026 at 20:35
Jailbreak is a daring escape from digital confinement. Bypassing security, it grants freedom to restricted systems. Risky yet thrilling, it challenges norms and boundaries. Like a digital heist, it requires skill and precision. Freedom comes with responsibility, as consequences may follow. <a href=https://images.google.co.zm/url?q=http://53o7o7gqt2oy67ufgm3mutefrrx3gllu4oe3ds7e4k3wny32yasqaoqd.onion>jailbailt & teen
</a>
Grace Steere on Monday, June 22, 2026 at 21:15
We are specialists in producing high-quality video content tailored for business websites and marketing. We create something that showcases your brand effectively—see a sample here:
Adding the right video to your website can dramatically improve user experience and lead generation. We have helped numerous businesses do exactly that—watch this quick example:https://www.youtube.com/shorts/SglkEN-n7_U
Harlan Mcmullen on Wednesday, June 24, 2026 at 04:34
Ready to drive targeted visitors to your dzhang.com site? This quick video explains how our AI works: https://www.youtube.com/watch?v=UEooLHpFYW0
CarlosShoor on Thursday, June 25, 2026 at 09:04
Erythroxylum coca is a plant species native to South America and is known for its historical, cultural, and botanical significance. Information about Erythroxylum coca seeds can be found through various online sources, including botanical databases<a href=https://erythroxylacoca.site>#ErythroxylumCoca
</a>
Mickie Prowse on Friday, June 26, 2026 at 00:27
Struggling to get targeted leads to your Dzhang Com website? Watch this: https://www.youtube.com/watch?v=UEooLHpFYW0
Carmon Corbitt on Saturday, June 27, 2026 at 17:40
Boost your website’s audience with our AI-powered traffic service, delivering targeted visitors at a lower cost than paid ads. Contact us today.
https://cutt.ly/Xt4CHGyz
Layla Clayton on Monday, June 29, 2026 at 05:26
Struggling to get targeted leads to your dzhang.com website? Watch this: https://www.youtube.com/watch?v=UEooLHpFYW0
Clark B. on Monday, June 29, 2026 at 21:21
Hi,
I’ve got a simple collab idea — I can place links to your site - dzhang.com on 5 legit local business websites (DR30+, ~2k–5k monthly traffic), completely free.
In return, you’d link to 5 of my client sites. Clean, fair exchange for a mutual SEO boost.
Let me know if you’re open to it.
Best,
Clark
Depinder Bharti on Sunday, April 25, 2010 at 11:40
Exactly, The reason how i came here is i was also facing the same problem and not able to understood what is happening and where i am going wrong.
In my case when i aborted, from application side it shows its aborted also application sometimes hangs, but in actual the request was still receiving data and it only stops after completing.