Skip to content

Commit c1a2053

Browse files
committed
Support timeout on WebRequestAsyncExtensions (Fix #18)
1 parent e477d13 commit c1a2053

File tree

1 file changed

+55
-10
lines changed

1 file changed

+55
-10
lines changed

src/NETStandard.WindowsCE/Net/WebRequestAsyncExtensions.cs

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.IO;
2+
using System.Threading;
23
using System.Threading.Tasks;
34

45
namespace 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

Comments
 (0)