public static Task<string> DownloadStringTaskAsync(this WebClient client,
    Uri address)
{
    var tcs = new TaskCompletionSource<string>();

    // Procedura obsługi zdarzeń zakończy zadanie i wyrejestruje się.
    DownloadStringCompletedEventHandler handler = null;
    handler = (_, e) =>
    {
        client.DownloadStringCompleted -= handler;
        if (e.Cancelled)
            tcs.TrySetCanceled();
        else if (e.Error != null)
            tcs.TrySetException(e.Error);
        else
            tcs.TrySetResult(e.Result);
    };

    // Zarejestrowanie zdarzenia, a następnie rozpoczęcie operacji.
    client.DownloadStringCompleted += handler;
    client.DownloadStringAsync(address);

    return tcs.Task;
}

---

public static Task<string> DownloadStringTaskAsync(this WebClient client,
    Uri address)
{
    var tcs = new TaskCompletionSource<string>();

    // Procedura obsługi zdarzeń zakończy zadanie i wyrejestruje się.
    DownloadStringCompletedEventHandler handler = null;
    handler = (_, e) =>
    {
        client.DownloadStringCompleted -= handler;
        tcs.TryCompleteFromEventArgs(e, () => e.Result);
    };

    // Zarejestrowanie zdarzenia, a następnie rozpoczęcie operacji.
    client.DownloadStringCompleted += handler;
    client.DownloadStringAsync(address);

    return tcs.Task;
}

---

public static Task<WebResponse> GetResponseAsync(this WebRequest client)
{
    return Task<WebResponse>.Factory.FromAsync(client.BeginGetResponse,
        client.EndGetResponse, null);
}

---

public interface IMyAsyncHttpService
{
    void DownloadString(Uri address, Action<string, Exception> callback);
}

---

public static Task<string> DownloadStringAsync(
    this IMyAsyncHttpService httpService, Uri address)
{
    var tcs = new TaskCompletionSource<string>();
    httpService.DownloadString(address, (result, exception) =>
    {
        if (exception != null)
            tcs.TrySetException(exception);
        else
            tcs.TrySetResult(result);
    });
    return tcs.Task;
}

---

await Task.Run(() => Parallel.ForEach(...));
---

IObservable<int> observable = ...;
int lastElement = await observable.LastAsync();
// lub: int lastElement = await observable;

---

IObservable<int> observable = ...;
int nextElement = await observable.FirstAsync();

---

IObservable<int> observable = ...;
IList<int> allElements = await observable.ToList();

---

var client = new HttpClient();
IObservable<HttpResponseMessage> response =
    client.GetAsync("http://www.example.com/")
    .ToObservable();

---

var client = new HttpClient();
IObservable<HttpResponseMessage> response = Observable
    .StartAsync(token => client.GetAsync("http://www.example.com/", token));

---

var client = new HttpClient();
IObservable<HttpResponseMessage> response = Observable
    .FromAsync(token => client.GetAsync("http://www.example.com/", token));

---

IObservable<string> urls = ...
var client = new HttpClient();
IObservable<HttpResponseMessage> responses = urls
    .SelectMany((url, token) => client.GetAsync(url, token));

---

var buffer = new BufferBlock<int>();
IObservable<int> integers = buffer.AsObservable();
integers. Subscribe(data => Trace.WriteLine(data),
    ex => Trace.WriteLine(ex),
    () => Trace.WriteLine("Zrobione"));

buffer.Post(13);

---

IObservable<DateTimeOffset> ticks =
    Observable.Interval(TimeSpan.FromSeconds(1))
    .Timestamp()
    . Select(x => x.Timestamp)
    .Take(5);

var display = new ActionBlock<DateTimeOffset>(x => Trace.WriteLine(x));
ticks.Subscribe(display.AsObserver());

try
{
    display.Completion.Wait();
    Trace.WriteLine("Zrobione.");
}
catch (Exception ex)
{
    Trace.WriteLine(ex);
}
