11using System . IO ;
2+ using System . Threading ;
23using System . Threading . Tasks ;
34
45namespace System . Net
@@ -16,12 +17,12 @@ public static class WebRequestAsyncExtensions
1617 /// <returns>The task object representing the asynchronous operation.</returns>
1718 public static Task < Stream > GetRequestStreamAsync ( this WebRequest source )
1819 {
20+ var function = source . Timeout > 0
21+ ? ( Func < object , Task < Stream > > ) ExecuteGetRequestStreamAsyncWithTimeout
22+ : ( Func < object , Task < Stream > > ) ExecuteGetRequestStreamAsync ;
23+
1924 // Offload to a different thread to avoid blocking the caller during request submission.
20- return Task . Run ( ( ) =>
21- Task . Factory . FromAsync (
22- ( callback , state ) => ( ( WebRequest ) state ) . BeginGetRequestStream ( callback , state ) ,
23- iar => ( ( WebRequest ) iar . AsyncState ) . EndGetRequestStream ( iar ) ,
24- source ) ) ;
25+ return Task . Factory . StartNew ( function , source ) . Unwrap ( ) ;
2526 }
2627
2728 /// <summary>
@@ -31,12 +32,56 @@ public static Task<Stream> GetRequestStreamAsync(this WebRequest source)
3132 /// <returns>The task object representing the asynchronous operation.</returns>
3233 public static Task < WebResponse > GetResponseAsync ( this WebRequest source )
3334 {
35+ var function = source . Timeout > 0
36+ ? ( Func < object , Task < WebResponse > > ) ExecuteGetResponseAsyncWithTimeout
37+ : ( Func < object , Task < WebResponse > > ) ExecuteGetResponseAsync ;
38+
3439 // See comment in GetRequestStreamAsync(). Same logic applies here.
35- return Task . Run ( ( ) =>
36- Task . Factory . FromAsync (
37- ( callback , state ) => ( ( WebRequest ) state ) . BeginGetResponse ( callback , state ) ,
38- iar => ( ( WebRequest ) iar . AsyncState ) . EndGetResponse ( iar ) ,
39- source ) ) ;
40+ return Task . Factory . StartNew ( function , source ) . Unwrap ( ) ;
41+ }
42+
43+ private static Task < Stream > ExecuteGetRequestStreamAsync ( object state )
44+ {
45+ return Task . Factory . FromAsync (
46+ ( callback , state2 ) => ( ( WebRequest ) state2 ) . BeginGetRequestStream ( callback , state2 ) ,
47+ iar => ( ( WebRequest ) iar . AsyncState ) . EndGetRequestStream ( iar ) ,
48+ state ) ;
49+ }
50+
51+ private static Task < Stream > ExecuteGetRequestStreamAsyncWithTimeout ( object state )
52+ {
53+ var source = ( WebRequest ) state ;
54+ var timer = new Timer ( s => ( ( WebRequest ) s ) . Abort ( ) , source , source . Timeout , Timeout . Infinite ) ;
55+ var task = Task . Factory . FromAsync (
56+ ( callback , state2 ) => ( ( WebRequest ) state2 ) . BeginGetRequestStream ( callback , state2 ) ,
57+ iar => ( ( WebRequest ) iar . AsyncState ) . EndGetRequestStream ( iar ) ,
58+ state ) ;
59+ task . ContinueWith (
60+ ( t , s ) => ( ( Timer ) s ) . Dispose ( ) ,
61+ timer ) ;
62+ return task ;
63+ }
64+
65+ private static Task < WebResponse > ExecuteGetResponseAsync ( object state )
66+ {
67+ return Task . Factory . FromAsync (
68+ ( callback , state2 ) => ( ( WebRequest ) state2 ) . BeginGetResponse ( callback , state2 ) ,
69+ iar => ( ( WebRequest ) iar . AsyncState ) . EndGetResponse ( iar ) ,
70+ state ) ;
71+ }
72+
73+ private static Task < WebResponse > ExecuteGetResponseAsyncWithTimeout ( object state )
74+ {
75+ var source = ( WebRequest ) state ;
76+ var timer = new Timer ( s => ( ( WebRequest ) s ) . Abort ( ) , source , source . Timeout , Timeout . Infinite ) ;
77+ var task = Task . Factory . FromAsync (
78+ ( callback , state2 ) => ( ( WebRequest ) state2 ) . BeginGetResponse ( callback , state2 ) ,
79+ iar => ( ( WebRequest ) iar . AsyncState ) . EndGetResponse ( iar ) ,
80+ state ) ;
81+ task . ContinueWith (
82+ ( t , s ) => ( ( Timer ) s ) . Dispose ( ) ,
83+ timer ) ;
84+ return task ;
4085 }
4186 }
4287}
0 commit comments