---
title: "Reactive Extensions (Rx) - Part 6 - Task ToObservable - Muhammad Rehan Saeed"
description: "How and where to use the Reactive Extensions (Rx) ToObservable Extension method to turn a Task Parallel Library (TPL) Task into an IObservable."
canonical_url: "https://rehansaeed.com/reactive-extensions-part6-task-toobservable/"
last_updated: "2014-04-25T00:00:00+00:00"
meta:
  author: "Muhammad Rehan Saeed"
  keywords: ".NET,C#,Reactive Extensions,Rx,Task Parallel Library,TPL"
  "og:description": "How and where to use the Reactive Extensions (Rx) ToObservable Extension method to turn a Task Parallel Library (TPL) Task into an IObservable."
  "og:image": "https://rehansaeed.com/_og/s/o_1a41408241bc3c0e.png"
  "og:image:alt": "Reactive Extensions (Rx) - Part 6 - Task ToObservable - Muhammad Rehan Saeed"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Reactive Extensions (Rx) - Part 6 - Task ToObservable"
  "twitter:image": "https://rehansaeed.com/_og/s/o_1a41408241bc3c0e.png"
  "twitter:image:alt": "Reactive Extensions (Rx) - Part 6 - Task ToObservable - Muhammad Rehan Saeed"
---

> Index of every page on this site: [llms.txt](https://rehansaeed.com/llms.txt)

# [Reactive Extensions (Rx) - Part 6 - Task ToObservable](https://rehansaeed.com/reactive-extensions-part6-task-toobservable/)

Posted 25 April 2014 - **5 min read**

![Reactive Extensions](https://rehansaeed.com/_ipx/f_png&s_2560x1440/images/hero/Reactive-Extensions-1366x768.png)

1. [Reactive Extensions (Rx) - Replacing C# Events](https://rehansaeed.com/reactive-extensions-part1-replacing-events/)
2. [Reactive Extensions (Rx) - Wrapping C# Events](https://rehansaeed.com/reactive-extensions-part2-wrapping-events/)
3. [Reactive Extensions (Rx) - Naming Conventions](https://rehansaeed.com/reactive-extensions-part3-naming-conventions/)
4. [Reactive Extensions (Rx) - Replacing Timers](https://rehansaeed.com/reactive-extensions-part4-replacing-timers/)
5. [Reactive Extensions (Rx) - Awaiting Observables](https://rehansaeed.com/reactive-extensions-part5-awaiting-observables/)
6. [Reactive Extensions (Rx) - Task ToObservable](https://rehansaeed.com/reactive-extensions-part6-task-toobservable/)
7. [Reactive Extensions (Rx) - Sample Events](https://rehansaeed.com/reactive-extensions-part7-sample-events/)
8. [Reactive Extensions (Rx) - Timeouts](https://rehansaeed.com/reactive-extensions-rx-part-8-timeouts/)

# A Quick Recap Link to this section

In my previous posts on Reactive Extensions (Rx) I've outlined a few clear areas where Reactive Extensions can be used in the real world. I've uncovered areas where it provides a cleaner and improved API surface as compared to older .NET code. Namely, replacing C# events, wrapping existing C# events and replacing `System.Threading.Timers` (Or other `Timer` classes, of which there are a few in .NET).

Once you have your observables, you need to do something with them. In my last post on the subject I showed how and when you can await an observable.

In this post I'm going to show how you can also go the other way around. You can turn tasks into an observable. I'll also show one clear reason to use this facility.

# Converting Tasks to Observables Link to this section

The `ToObservable` extension method allows you to convert a Task or `Task<T>` into an `IObservable<T>`. Calling `ToObservable` on a `Task` returns an `IObservable<Unit>`. A `Unit` is a kind of empty object that does nothing, the only reason it is there is because there is no `IObservable` (Without the `T`) interface.

```cs
IObservable<Unit> observable = Task.Run(() => Console.WriteLine("Working")).ToObservable();

IObservable<string> observableT = Task<string>.Run(() => "Working").ToObservable();
```

If you subscribe to the above observables, they will only ever return one value and then complete. You might be thinking, hang on just a second Rehan, whats the point of doing this?

# Putting It All Together Link to this section

So when should we use this feature? Well, lets walk through some examples and see what happens. Lets assume we have the following contrived code:

```cs
public Task<string> GetHelloString()
{
    return Task.Run(
        async () =>
        {
            await Task.Delay(500);
            return "Hello";
        });
}

public Task<string> GetWorldString()
{
    return Task.Run(
        async () =>
        {
            await Task.Delay(1000);
            return "World";
        });
}
```

What happens in the case where we call both of these methods and want to get the first result back. How does this code look using the Task Parallel Library (TPL) as compared to Reactive Extensions (Rx).

```cs
public async Task<string> WaitForFirstResultAndReturn()
{
    Task<string> task1 = this.GetHelloString();
    Task<string> task2 = this.GetWorldString();

    return await Task.WhenAny(task1, task2);
}

public async Task<string> WaitForFirstResultAndReturn()
{
    IObservable<string> observable1 = this.GetHelloString().ToObservable();
    IObservable<string> observable2 = this.GetWorldString().ToObservable();

    return await observable1.Merge(observable2).FirstAsync();
}
```

In the Task Parallel Library (TPL) example, I simply use the `WhenAny` method to await the first task that completes and then return the result.

In the Reactive Extensions example above, I'm converting my tasks to observables, using the Merge method to convert them to a single observable and then using the `FirstAsync` method to await the first result (We covered `await`'ing observables in the last post).

Overall the two techniques look pretty similar, with the TPL having a slight edge in terms of simplicity.

How about another example. Here we will try to await both of the results and put them together to get some meaningful result.

```cs
public async Task<string> WaitForAllResultsAndReturnCombinedResult()
{
    Task<string> task1 = this.GetHelloString();
    Task<string> task2 = this.GetWorldString();

    return string.Join(" ", await Task.WhenAll(task1, task2));
}

public async Task<string> WaitForAllResultsAndReturnCombinedResult()
{
    IObservable<string> observable1 = this.GetHelloString().ToObservable();
    IObservable<string> observable2 = this.GetWorldString().ToObservable();

    return await observable1.Zip(observable2, (x1, x2) => string.Join(" ", x1, x2));
}
```

In the Task Parallel Library (TPL) example, I'm using the `WhenAll` method to await the results of both tasks which are returned as an array of strings. I then join these strings and return the results.

In the Reactive Extensions example above, I'm converting my tasks to observables, then using the `Zip` method to combine the results returned from both observables by providing it with a delegate which joins the two strings.

Again, both look pretty similar but with the pure TPL example being slightly simpler to understand.

One more example, this time we'll return the first result but add a timeout to the equation.

```cs
public async Task<string> WaitForFirstResultAndReturnResultWithTimeOut()
{
    Task<string> task1 = this.GetHelloString();
    Task<string> task2 = this.GetWorldString();
    Task timeoutTask = Task.Delay(100);

    Task completedTask = await Task.WhenAny(task1, task2, timeoutTask);
    if (completedTask == timeoutTask)
    {
        throw new TimeoutException("The operation has timed out");
    }

    return ((Task<string>)completedTask).Result;
}

public async Task<string> WaitForFirstResultAndReturnResultWithTimeOut()
{
    IObservable<string> observable1 = this.GetHelloString().ToObservable();
    IObservable<string> observable2 = this.GetWorldString().ToObservable();

    return await observable1.Merge(observable2).Timeout(TimeSpan.FromMilliseconds(100)).FirstAsync();
}
```

In the Task Parallel Library (TPL) example, I'm awaiting a third task which represents the timeout. If the timeout task finishes first, I raise a `TimeoutException`.

In the Reactive Extensions example, we merge the two observables again but this time use the `Timeout` method to achieve the same results.

Here we have a clear winner, the Reactive Extensions code is more concise and easier to follow.

What happens when we combine the two approaches.

```cs
public async Task<string> WaitForFirstResultAndReturnResultWithTimeOut2()
{
    Task<string> task1 = this.GetHelloString();
    Task<string> task2 = this.GetWorldString();

    return await Task
        .WhenAny(task1, task2)
        .ToObservable()
        .Timeout(TimeSpan.FromMilliseconds(1000))
        .FirstAsync();
}
```

Here we use the `ToObservable` and `Timeout` methods right at the end. As you can see this combined approach gives us the best of both worlds and makes the code much easier to read.

# Conclusions Link to this section

One definite reason to convert `Task`'s to Observables is to use the `Timeout` method. There may be other reasons but I'm having a hard time thinking of any right now. In fact, I'm having a hard time thinking of any other posts to make about Reactive Extensions (Rx). It's an interesting chunk of code and I've learned a lot writing this series of posts as I hope you have too.

## Web Mentions

[What's this?](https://en.wikipedia.org/wiki/Webmention)

### 0 Linked

### 0 Replies

## GitHub Comments

### 7 Comments

[Comment on GitHub](https://github.com/RehanSaeed/rehansaeed.github.io/issues/108)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Dennis Daume](https://camo.githubusercontent.com/41d0d601b732f2f9ede4254d00897b584f8db416bfe6085d188ad9b5e062fe5b/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30326137643436626133363764616364363566386435363839346336336139373f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/41d0d601b732f2f9ede4254d00897b584f8db416bfe6085d188ad9b5e062fe5b/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f30326137643436626133363764616364363566386435363839346336336139373f733d393626643d6d6d26723d67) **[Dennis Daume](http://twitter.com/flagbug)** commented on **2014-04-25 20:19:20**

I think instead of `obs1.Merge(obs2).FirstAsync` you can write `obs1.Amb(obs2)` to get the first responding sequence :)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Daniel](https://camo.githubusercontent.com/10fa236d10e8f2aed39ba67e67a063ff39f14b9b9e95eb1f46749c859634c261/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31643864386163373739386664363038343138356330376263376333393433333f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/10fa236d10e8f2aed39ba67e67a063ff39f14b9b9e95eb1f46749c859634c261/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31643864386163373739386664363038343138356330376263376333393433333f733d393626643d6d6d26723d67) **Daniel** commented on **2015-12-29 09:37:32**

Thank you for showing clear, practical code!  
 I think the TPL vs Rx solutions in the timeout example aren't doing the same thing though:

- TPL: the `Task.Delay()` runs in parallel, making the timeout count from the start.
- Rx: `.Timeout()` counts from last item yielded (http://reactivex.io/documentation/operators/timeout.html)

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2016-01-07 16:22:26**

> Thank you for showing clear, practical code!  
>  I think the TPL vs Rx solutions in the timeout example aren't doing the same thing though:
>
> - TPL: the `Task.Delay()` runs in parallel, making the timeout count from the start.
> - Rx: `.Timeout()` counts from last item yielded (http://reactivex.io/documentation/operators/timeout.html)

Yes but there is only one item yielded from each observable. Perhaps I have misunderstood you.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Daniel](https://camo.githubusercontent.com/10fa236d10e8f2aed39ba67e67a063ff39f14b9b9e95eb1f46749c859634c261/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31643864386163373739386664363038343138356330376263376333393433333f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/10fa236d10e8f2aed39ba67e67a063ff39f14b9b9e95eb1f46749c859634c261/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f31643864386163373739386664363038343138356330376263376333393433333f733d393626643d6d6d26723d67) **Daniel** commented on **2016-01-10 21:37:30**

> Yes but there is only one item yielded from each observable. Perhaps I have misunderstood you.

True, my bad, thanks for the response.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Guan George](https://camo.githubusercontent.com/2bf912a07912c809bd0cc5ba465602e8d6c37b226a14daae4cf3e9978c015719/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f36623133383966393665346239326366386565383431613065396563383862373f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/2bf912a07912c809bd0cc5ba465602e8d6c37b226a14daae4cf3e9978c015719/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f36623133383966393665346239326366386565383431613065396563383862373f733d393626643d6d6d26723d67) **Guan George** commented on **2017-11-17 21:05:34**

Very good and helpful. Thanks for your blog. ^\_^

One suggestion, `Task.Run(async...)` can be removed like this:

```
public async static Task GetHelloString()
{
    await Task.Delay(2000);
    return "Hello";
}
```

One correction: should we use `await await` instead of `await` cause `WhenAny` returns `Task<Task>`?  
 if only one `await`, complier will not succeed (At least in my VS 2015 ^\_^).

```
public async static Task<string> WaitForFirstResultAndReturnResultWithTimeOut2()
{
    Task<string> task1 = GetHelloString();
    Task<string> task2 = GetWorldString();
    return await await Task.WhenAny(task1, task2)
        .ToObservable()
        .Timeout(TimeSpan.FromMilliseconds(500))
        .FirstAsync();
}
```

I started learn C# 1 week ago, so my option may be wrong. Sorry if.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Muhammad Rehan Saeed](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/8a07049df41b8a3839a3f4342f09ea8e6e7fa0065667687f04beca2d088a1dca/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f32623266393030653361633066353535316462646537323864336262343935343f733d393626643d6d6d26723d67) **[Muhammad Rehan Saeed](https://rehansaeed.com/)** commented on **2017-11-20 08:35:16**

> Very good and helpful. Thanks for your blog. ^\_^
>
> One suggestion, `Task.Run(async...)` can be removed like this:
>
> ```
> public async static Task GetHelloString()
> {
>     await Task.Delay(2000);
>     return "Hello";
> }
> ```
>
> One correction: should we use `await await` instead of `await` cause `WhenAny` returns `Task<Task>`?  
>  if only one `await`, complier will not succeed (At least in my VS 2015 ^\_^).
>
> ```
> public async static Task<string> WaitForFirstResultAndReturnResultWithTimeOut2()
> {
>     Task<string> task1 = GetHelloString();
>     Task<string> task2 = GetWorldString();
>     return await await Task.WhenAny(task1, task2)
>         .ToObservable()
>         .Timeout(TimeSpan.FromMilliseconds(500))
>         .FirstAsync();
> }
> ```
>
> I started learn C# 1 week ago, so my option may be wrong. Sorry if.

`Task.WhenAny` should not be returning a task of task unless you are doing something very strange.

[![RehanSaeed](https://avatars.githubusercontent.com/u/2270364?v=4)](https://github.com/RehanSaeed)

### [RehanSaeed](https://github.com/RehanSaeed)

Owner

12 May 2020

[![Frank](https://camo.githubusercontent.com/faaaae7b3e41d3c8d6c8bdc5ac6bf263f265e20babb6dc0ca32d76d5dd18f592/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643065396537373738396237343737353337373163343465663963666432383f733d393626643d6d6d26723d67)](https://camo.githubusercontent.com/faaaae7b3e41d3c8d6c8bdc5ac6bf263f265e20babb6dc0ca32d76d5dd18f592/68747470733a2f2f7777772e67726176617461722e636f6d2f6176617461722f37643065396537373738396237343737353337373163343465663963666432383f733d393626643d6d6d26723d67) **Frank** commented on **2018-01-23 15:47:51**

I am not sure yet, as I have not tested, but I think I see a need for this in Linq code of the kind `from x in y select f(x)`, where `f` is an `async` function and the result is an `IObservable<f(x)>`.

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://rehansaeed.com/#website","@type":"WebSite","description":"Software Developer at Microsoft, YouTuber, Open Source Contributor and Blogger","inLanguage":"en-GB","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/","author":{"@id":"https://rehansaeed.com/#identity"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://rehansaeed.com/?search={search_term_string}"},"query-input":"required name=search_term_string"}],"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#webpage","@type":"WebPage","dateModified":"2014-04-25T00:00:00+00:00","datePublished":"2014-04-25T00:00:00+00:00","description":"How and where to use the Reactive Extensions (Rx) ToObservable Extension method to turn a Task Parallel Library (TPL) Task into an IObservable.","name":"Reactive Extensions (Rx) - Part 6 - Task ToObservable","url":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/","breadcrumb":{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#breadcrumb"},"isPartOf":{"@id":"https://rehansaeed.com/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://rehansaeed.com/reactive-extensions-part6-task-toobservable/"]}]},{"@id":"https://rehansaeed.com/#identity","@type":"Person","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com/about/","image":{"@id":"https://rehansaeed.com/#/schema/image/1"},"sameAs":["https://github.com/RehanSaeed","https://www.linkedin.com/in/muhammad-rehan-saeed","https://stackoverflow.com/users/1212017/muhammad-rehan-saeed","https://www.youtube.com/c/MuhammadRehanSaeed","https://www.twitch.tv/rehansaeeduk"]},{"@id":"https://rehansaeed.com/#publisher","@type":"Organization","logo":"https://rehansaeed.com/images/schema/Publisher-600x60.png","name":"Muhammad Rehan Saeed","url":"https://rehansaeed.com"},{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#article","@type":"Article","dateModified":"2014-04-25T00:00:00+00:00","datePublished":"2014-04-25T00:00:00+00:00","description":"How and where to use the Reactive Extensions (Rx) ToObservable Extension method to turn a Task Parallel Library (TPL) Task into an IObservable.","headline":"Reactive Extensions (Rx) - Part 6 - Task ToObservable","inLanguage":"en-GB","url":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/","author":{"@id":"https://rehansaeed.com/#identity"},"image":[{"@type":"ImageObject","url":"https://rehansaeed.com/images/hero/Reactive-Extensions-1366x768.png","caption":"Reactive Extensions","width":"1366","height":"768"}],"isPartOf":{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#webpage"},"keywords":[".NET","C#","Reactive Extensions","Rx","Task Parallel Library","TPL"],"mainEntityOfPage":{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#webpage"},"publisher":{"@id":"https://rehansaeed.com/#publisher"}},{"@id":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://rehansaeed.com/","position":1},{"@type":"ListItem","name":"Reactive Extensions (Rx) - Part 6 - Task ToObservable","item":"https://rehansaeed.com/reactive-extensions-part6-task-toobservable/","position":2}]},{"@id":"https://rehansaeed.com/#/schema/image/1","@type":"ImageObject","contentUrl":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png","inLanguage":"en-GB","url":"https://rehansaeed.com/images/author/Muhammad-Rehan-Saeed/Logo-512x512.png"}]}
```

## Sitemap

See the full [sitemap](https://rehansaeed.com/sitemap.md) for all pages.
