While working on my House Ad Framework (part of my Advertising Network Manager XNA Component that starts its private-beta this week), I needed a way to download PNG files from the Internet asynchronously and specify a timeout, where the asynchronous request would abort if the wait period expired before receiving the image’s file stream. I searched the Web and found BeginGetResponse
and the sample code provided on that MSDN page. I modified it to load image files instead of HTML, but still couldn’t use it because IASyncResult.AsyncWaitHandle
throws an “unsupported” exception at run-time on Windows Phone. Other solutions that I found were similarly unsupported on WP7.
Fortunately, I soon found AutoResetEvent
, which can be used in place of AsyncWaitHandle
and provides a thread-blocking WaitOne
signaled timeout function, which can be put on a background thread in order to not block the main UI thread. I posted my code for doing the “asynchronous image download with abort on timeout” on the AppHub forum yesterday, and you’re welcome to it! I tested it briefly and it works, but if you find any bugs, please let me know.
Note that the code I posted uses a few simple things that won’t compile until you make some minor changes:
public static class DebugHelper {
[Conditional("DEBUG")]
public static void WriteLineMT(string text) {
Debug.WriteLine(DateTime.Now + " [" +
Thread.CurrentThread.ManagedThreadId + "]: " + text);
}
}
- My “
HouseAdFrame
” class “frame
” object – I didn’t provide the class, but the only things used from it are the “Image
” (an XNA Texture2D
object) and “ImagePath
” (a string
containing the image file URL) members. You should be able to easily replace the AsyncRequestState
“frame
” member with those two things.
- As noted above, this code loads an XNA
Texture2D
object from the response stream. If you are using Silverlight, you will need to change this to a Silverlight-compatible type.
- My “
removeFrameList
” code in the exception handlers (catch
-blocks). When the image-load fails, it means that the frame is going to be bad, so I put it on a list of frames to be removed on the next Update cycle. You will want to replace this exception handler code with your own error processing code.
- My use of the
DebugHelper.WriteLineMT
function, which is provided below for your reference:
Of course, as it usually goes, you spend hours figuring something out only to find that someone may have a better solution and it was freely available to you all along. While I haven’t tried it yet, you may want to check out Wintellect’s “Power Threading” library download by the amazing Jeffrey Richter. Having read many of his books over the years, it’s quite likely that while my solution may fill your immediate need, his solution will cover many usage scenarios that mine doesn’t.
Now go forth and download asynchronously to your heart’s content!