title: What to use if i want to return the result of a webclient
body: <p>take the following code:</p>
  
  <pre><code>    public async Task&lt;string&gt; AuthenticatedGetData(string url, string token)
      {
          WebClient client = new WebClient();
          client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(WebClient_DownloadStringCompleted);
          client.DownloadStringAsync(new Uri(url + "?oauth_token=" + token));
      }
  
      private void WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
      {
          string response = e.Result;    
      }
  </code></pre>
  
  <p>WebClient_DownloadStringCompleted gets called... and response = the response I want... Great. perfect... </p>
  
  <p><strong>Now consider how i'm calling this AuthenticatedGetData method:</strong></p>
  
  <p>It is being called from a kind of repository... The repository wants a string so that it can serialize and do stuff with the resulting object...</p>
  
  <p>So everything is running async fromt he repository... The call gets made to the authenticatedgetdata, it then makes a request... but because the downloadstringasync does not have a .Result() method and because downloadstringcompleted requires a void method to call... I cannot return the result string to the calling repository.</p>
  
  <p>Any ideas on what I must do to get client.DownloadStringAsync to return the response string on completion?</p>
  
  <p>Is it that I just simply have to tightly couple my data access operations to this specific app.. It seems so un..re-usable :( I really want to keep my whole authentication stuff totally separate from what's going to happen. and I do not want to keep repeating the above code for each repository, because it's going to be the same for each anyway!</p>
  
  <p><strong>Edit:://</strong></p>
  
  <p>I've created an abstract method in my class that deals with the above requests... and then I extend this class with my repository and implement the abstract method. sound good?</p>
  
  <p><strong>Edit://</strong> Calling code as requested:</p>
  
  <pre><code>public class OrganisationRepository
  {
      PostRequest postRequest;
  
      public OrganisationRepository()
      {
          this.postRequest = new PostRequest();
      }
      public IEnumerable&lt;Organisation&gt; GetAll()
      {
          string requestUrl = BlaBla.APIURL + "/org/";
          string response = postRequest.AuthenticatedGetData(requestUrl, BlaBla.Contract.AccessToken).Result;
      }
  }
  
  public class PostRequest
  {
  
      public Task&lt;string&gt; AuthenticatedGetData(string url, string token)
      {
  
          TaskCompletionSource&lt;string&gt; tcs = new TaskCompletionSource&lt;string&gt;();
  
          WebClient client = new WebClient();
          client.DownloadStringCompleted += (sender, e) =&gt;
          {
              if (e.Error != null)
              {
                  tcs.TrySetException(e.Error);
              }
              else if (e.Cancelled)
              {
                  tcs.TrySetCanceled();
              }
              else
              {
                  tcs.TrySetResult(e.Result);
              }
          };
          client.DownloadStringAsync(new Uri(url + "?oauth_token=" + token));
          return tcs.Task;
      }
  }
  </code></pre>