All files
[pithos-ms-client] / trunk / Libraries / ParallelExtensionsExtras / Extensions / EAP / WebClientExtensions.cs
1 //--------------------------------------------------------------------------
2 // 
3 //  Copyright (c) Microsoft Corporation.  All rights reserved. 
4 // 
5 //  File: WebClientExtensions.cs
6 //
7 //--------------------------------------------------------------------------
8
9 using System.ComponentModel;
10 using System.IO;
11 using System.Threading.Tasks;
12
13 namespace System.Net
14 {
15     /// <summary>Extension methods for working with WebClient asynchronously.</summary>
16     public static class WebClientExtensions
17     {
18         /// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
19         /// <param name="webClient">The WebClient.</param>
20         /// <param name="address">The URI from which to download data.</param>
21         /// <returns>A Task that contains the downloaded data.</returns>
22         public static Task<byte[]> DownloadDataTask(this WebClient webClient, string address)
23         {
24             return DownloadDataTask(webClient, new Uri(address));
25         }
26
27         /// <summary>Downloads the resource with the specified URI as a byte array, asynchronously.</summary>
28         /// <param name="webClient">The WebClient.</param>
29         /// <param name="address">The URI from which to download data.</param>
30         /// <returns>A Task that contains the downloaded data.</returns>
31         public static Task<byte[]> DownloadDataTask(this WebClient webClient, Uri address)
32         {
33             // Create the task to be returned
34             var tcs = new TaskCompletionSource<byte[]>(address);
35
36             // Setup the callback event handler
37             DownloadDataCompletedEventHandler handler = null;
38             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadDataCompleted -= handler);
39             webClient.DownloadDataCompleted += handler;
40
41             // Start the async work
42             try
43             {
44                 webClient.DownloadDataAsync(address, tcs);
45             }
46             catch(Exception exc)
47             {
48                 // If something goes wrong kicking off the async work,
49                 // unregister the callback and cancel the created task
50                 webClient.DownloadDataCompleted -= handler;
51                 tcs.TrySetException(exc);
52             }
53
54             // Return the task that represents the async operation
55             return tcs.Task;
56         }
57
58         /// <summary>Downloads the resource with the specified URI to a local file, asynchronously.</summary>
59         /// <param name="webClient">The WebClient.</param>
60         /// <param name="address">The URI from which to download data.</param>
61         /// <param name="fileName">The name of the local file that is to receive the data.</param>
62         /// <returns>A Task that contains the downloaded data.</returns>
63         public static Task DownloadFileTask(this WebClient webClient, string address, string fileName)
64         {
65             return DownloadFileTask(webClient, new Uri(address), fileName);
66         }
67
68         /// <summary>Downloads the resource with the specified URI to a local file, asynchronously.</summary>
69         /// <param name="webClient">The WebClient.</param>
70         /// <param name="address">The URI from which to download data.</param>
71         /// <param name="fileName">The name of the local file that is to receive the data.</param>
72         /// <returns>A Task that contains the downloaded data.</returns>
73         public static Task DownloadFileTask(this WebClient webClient, Uri address, string fileName)
74         {
75             // Create the task to be returned
76             var tcs = new TaskCompletionSource<object>(address);
77             
78             // Setup the callback event handler
79             AsyncCompletedEventHandler handler = null;
80             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => null, () => webClient.DownloadFileCompleted -= handler);
81             webClient.DownloadFileCompleted += handler;
82
83             // Start the async work
84             try
85             {
86                 webClient.DownloadFileAsync(address, fileName, tcs);
87             }
88             catch(Exception exc)
89             {
90                 // If something goes wrong kicking off the async work,
91                 // unregister the callback and cancel the created task
92                 webClient.DownloadFileCompleted -= handler;
93                 tcs.TrySetException(exc);
94             }
95
96             // Return the task that represents the async operation
97             return tcs.Task;
98         }
99
100         /// <summary>Downloads the resource with the specified URI as a string, asynchronously.</summary>
101         /// <param name="webClient">The WebClient.</param>
102         /// <param name="address">The URI from which to download data.</param>
103         /// <returns>A Task that contains the downloaded string.</returns>
104         public static Task<string> DownloadStringTask(this WebClient webClient, string address)
105         {
106             return DownloadStringTask(webClient, new Uri(address));
107         }
108
109         /// <summary>Downloads the resource with the specified URI as a string, asynchronously.</summary>
110         /// <param name="webClient">The WebClient.</param>
111         /// <param name="address">The URI from which to download data.</param>
112         /// <returns>A Task that contains the downloaded string.</returns>
113         public static Task<string> DownloadStringTask(this WebClient webClient, Uri address)
114         {
115             // Create the task to be returned
116             var tcs = new TaskCompletionSource<string>(address);
117
118             // Setup the callback event handler
119             DownloadStringCompletedEventHandler handler = null;
120             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.DownloadStringCompleted -= handler);
121             webClient.DownloadStringCompleted += handler;
122
123             // Start the async work
124             try
125             {
126                 webClient.DownloadStringAsync(address, tcs);
127             }
128             catch(Exception exc)
129             {
130                 // If something goes wrong kicking off the async work,
131                 // unregister the callback and cancel the created task
132                 webClient.DownloadStringCompleted -= handler;
133                 tcs.TrySetException(exc);
134             }
135
136             // Return the task that represents the async operation
137             return tcs.Task;
138         }
139
140         /// <summary>Opens a readable stream for the data downloaded from a resource, asynchronously.</summary>
141         /// <param name="webClient">The WebClient.</param>
142         /// <param name="address">The URI for which the stream should be opened.</param>
143         /// <returns>A Task that contains the opened stream.</returns>
144         public static Task<Stream> OpenReadTask(this WebClient webClient, string address)
145         {
146             return OpenReadTask(webClient, new Uri(address));
147         }
148
149         /// <summary>Opens a readable stream for the data downloaded from a resource, asynchronously.</summary>
150         /// <param name="webClient">The WebClient.</param>
151         /// <param name="address">The URI for which the stream should be opened.</param>
152         /// <returns>A Task that contains the opened stream.</returns>
153         public static Task<Stream> OpenReadTask(this WebClient webClient, Uri address)
154         {
155             // Create the task to be returned
156             var tcs = new TaskCompletionSource<Stream>(address);
157
158             // Setup the callback event handler
159             OpenReadCompletedEventHandler handler = null;
160             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.OpenReadCompleted -= handler);
161             webClient.OpenReadCompleted += handler;
162
163             // Start the async work
164             try
165             {
166                 webClient.OpenReadAsync(address, tcs);
167             }
168             catch(Exception exc)
169             {
170                 // If something goes wrong kicking off the async work,
171                 // unregister the callback and cancel the created task
172                 webClient.OpenReadCompleted -= handler;
173                 tcs.TrySetException(exc);
174             }
175
176             // Return the task that represents the async operation
177             return tcs.Task;
178         }
179
180         /// <summary>Opens a writeable stream for uploading data to a resource, asynchronously.</summary>
181         /// <param name="webClient">The WebClient.</param>
182         /// <param name="address">The URI for which the stream should be opened.</param>
183         /// <param name="method">The HTTP method that should be used to open the stream.</param>
184         /// <returns>A Task that contains the opened stream.</returns>
185         public static Task<Stream> OpenWriteTask(this WebClient webClient, string address, string method)
186         {
187             return OpenWriteTask(webClient, new Uri(address), method);
188         }
189
190         /// <summary>Opens a writeable stream for uploading data to a resource, asynchronously.</summary>
191         /// <param name="webClient">The WebClient.</param>
192         /// <param name="address">The URI for which the stream should be opened.</param>
193         /// <param name="method">The HTTP method that should be used to open the stream.</param>
194         /// <returns>A Task that contains the opened stream.</returns>
195         public static Task<Stream> OpenWriteTask(this WebClient webClient, Uri address, string method)
196         {
197             // Create the task to be returned
198             var tcs = new TaskCompletionSource<Stream>(address);
199
200             // Setup the callback event handler
201             OpenWriteCompletedEventHandler handler = null;
202             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.OpenWriteCompleted -= handler);
203             webClient.OpenWriteCompleted += handler;
204
205             // Start the async work
206             try
207             {
208                 webClient.OpenWriteAsync(address, method, tcs);
209             }
210             catch(Exception exc)
211             {
212                 // If something goes wrong kicking off the async work,
213                 // unregister the callback and cancel the created task
214                 webClient.OpenWriteCompleted -= handler;
215                 tcs.TrySetException(exc);
216             }
217             
218             // Return the task that represents the async operation
219             return tcs.Task;
220         }
221
222         /// <summary>Uploads data to the specified resource, asynchronously.</summary>
223         /// <param name="webClient">The WebClient.</param>
224         /// <param name="address">The URI to which the data should be uploaded.</param>
225         /// <param name="method">The HTTP method that should be used to upload the data.</param>
226         /// <param name="data">The data to upload.</param>
227         /// <returns>A Task containing the data in the response from the upload.</returns>
228         public static Task<byte[]> UploadDataTask(this WebClient webClient, string address, string method, byte[] data)
229         {
230             return UploadDataTask(webClient, new Uri(address), method, data);
231         }
232
233         /// <summary>Uploads data to the specified resource, asynchronously.</summary>
234         /// <param name="webClient">The WebClient.</param>
235         /// <param name="address">The URI to which the data should be uploaded.</param>
236         /// <param name="method">The HTTP method that should be used to upload the data.</param>
237         /// <param name="data">The data to upload.</param>
238         /// <returns>A Task containing the data in the response from the upload.</returns>
239         public static Task<byte[]> UploadDataTask(this WebClient webClient, Uri address, string method, byte [] data)
240         {
241             // Create the task to be returned
242             var tcs = new TaskCompletionSource<byte[]>(address);
243
244             // Setup the callback event handler
245             UploadDataCompletedEventHandler handler = null;
246             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadDataCompleted -= handler);
247             webClient.UploadDataCompleted += handler;
248
249             // Start the async work
250             try
251             {
252                 webClient.UploadDataAsync(address, method, data, tcs);
253             }
254             catch(Exception exc)
255             {
256                 // If something goes wrong kicking off the async work,
257                 // unregister the callback and cancel the created task
258                 webClient.UploadDataCompleted -= handler;
259                 tcs.TrySetException(exc);
260             }
261
262             // Return the task that represents the async operation
263             return tcs.Task;
264         }
265
266         /// <summary>Uploads a file to the specified resource, asynchronously.</summary>
267         /// <param name="webClient">The WebClient.</param>
268         /// <param name="address">The URI to which the file should be uploaded.</param>
269         /// <param name="method">The HTTP method that should be used to upload the file.</param>
270         /// <param name="fileName">A path to the file to upload.</param>
271         /// <returns>A Task containing the data in the response from the upload.</returns>
272         public static Task<byte[]> UploadFileTask(this WebClient webClient, string address, string method, string fileName)
273         {
274             return UploadFileTask(webClient, new Uri(address), method, fileName);
275         }
276
277         /// <summary>Uploads a file to the specified resource, asynchronously.</summary>
278         /// <param name="webClient">The WebClient.</param>
279         /// <param name="address">The URI to which the file should be uploaded.</param>
280         /// <param name="method">The HTTP method that should be used to upload the file.</param>
281         /// <param name="fileName">A path to the file to upload.</param>
282         /// <returns>A Task containing the data in the response from the upload.</returns>
283         public static Task<byte[]> UploadFileTask(this WebClient webClient, Uri address, string method, string fileName)
284         {
285             // Create the task to be returned
286             var tcs = new TaskCompletionSource<byte[]>(address);
287
288             // Setup the callback event handler
289             UploadFileCompletedEventHandler handler = null;
290             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, () => webClient.UploadFileCompleted -= handler);
291             webClient.UploadFileCompleted += handler;
292
293             // Start the async work
294             try
295             {
296                 webClient.UploadFileAsync(address, method, fileName, tcs);
297             }
298             catch(Exception exc)
299             {
300                 // If something goes wrong kicking off the async work,
301                 // unregister the callback and cancel the created task
302                 webClient.UploadFileCompleted -= handler;
303                 tcs.TrySetException(exc);
304             }
305
306             // Return the task that represents the async operation
307             return tcs.Task;
308         }
309
310         /// <summary>Uploads data in a string to the specified resource, asynchronously.</summary>
311         /// <param name="webClient">The WebClient.</param>
312         /// <param name="address">The URI to which the data should be uploaded.</param>
313         /// <param name="method">The HTTP method that should be used to upload the data.</param>
314         /// <param name="data">The data to upload.</param>
315         /// <returns>A Task containing the data in the response from the upload.</returns>
316         public static Task<string> UploadStringTask(this WebClient webClient, string address, string method, string data)
317         {
318             return UploadStringTask(webClient, address, method, data);
319         }
320
321         /// <summary>Uploads data in a string to the specified resource, asynchronously.</summary>
322         /// <param name="webClient">The WebClient.</param>
323         /// <param name="address">The URI to which the data should be uploaded.</param>
324         /// <param name="method">The HTTP method that should be used to upload the data.</param>
325         /// <param name="data">The data to upload.</param>
326         /// <returns>A Task containing the data in the response from the upload.</returns>
327         public static Task<string> UploadStringTask(this WebClient webClient, Uri address, string method, string data)
328         {
329             // Create the task to be returned
330             var tcs = new TaskCompletionSource<string>(address);
331
332             // Setup the callback event handler
333             UploadStringCompletedEventHandler handler = null;
334             handler = (sender, e) => EAPCommon.HandleCompletion(tcs, e, () => e.Result, ()=> webClient.UploadStringCompleted -= handler);
335             webClient.UploadStringCompleted += handler;
336
337             // Start the async work
338             try
339             {
340                 webClient.UploadStringAsync(address, method, data, tcs);
341             }
342             catch(Exception exc)
343             {
344                 // If something goes wrong kicking off the async work,
345                 // unregister the callback and cancel the created task
346                 webClient.UploadStringCompleted -= handler;
347                 tcs.TrySetException(exc);
348             }
349
350             // Return the task that represents the async operation
351             return tcs.Task;
352         }
353     }
354 }