Wrap a callback method in an awaitable method
Error Handling

You are relying on OAuthGetRequestTokenAsync to catch all exceptions for you.


flickr.OAuthGetRequestTokenAsync(callbackUrl, r =&gt;
{
    if (r.HasError)
        tcs.TrySetException(r.Error);
    else
        tcs.TrySetResult(r.Result);
});



Unhandled errors

However, OAuthGetRequestTokenAsync internally calls  FlickrResponder.GetDataResponseAsync, which as you can see in the Reference Source does not catch all exceptions.

Most exceptions are caught and provided to the callback:


// .. snippet from FlickrNet.Internals.FlickrResponder.GetDataResponseAsync()
if (e.Error != null)
{
    result.Error = e.Error;
    callback(result);
    return;
}



But some are thrown to the caller:


// .. snippet from FlickrNet.Internals.FlickrResponder.GetDataResponseAsync()
using (var responseReader = new StreamReader(response.GetResponseStream()))
{
    string responseData = responseReader.ReadToEnd();

    throw new OAuthException(responseData, ex);
}





Refactored Code

To wrap this call in an async task, I would also catch these exceptions and handle them in the Task.TrySetException. In addition, since you provide a public API, I suggest to avoid NullReferenceException and check required arguments against null. Perhaps callbackUrl should also be checked early against null. I'm not sure about this, you'd have to verify.

public static Task&lt;OAuthRequestToken&gt; OAuthGetRequestTokenAsync(
    this Flickr flickr, string callbackUrl)
{
    if (flickr == null) throw new ArgumentNullException(nameof(flickr));
    var tcs = new TaskCompletionSource&lt;OAuthRequestToken&gt;();
    try
    {
        flickr.OAuthGetRequestTokenAsync(callbackUrl, r =&gt;
        {
            if (r.HasError)
                tcs.TrySetException(r.Error);
            else
                tcs.TrySetResult(r.Result);
        });
    } 
    catch (Exception uncaughtError)
    {
        tcs.TrySetException(uncaughtError);
    }

    return tcs.Task;
}