Behavioral difference between Concat and Merge(1)
- Dominant language
- C#
- Stars
- 7.2k
- Forks
- 798
- PR merge metrics
- No merged PRs in 30d
Description
Hi! I was under the impression that the `Concat` operator is equivalent to the `Merge(1)` operator, since both operators subscribe at one subsequence at a time ([this](https://github.com/dotnet/reactive/pull/491) pull request reinforces this impression). But I discovered a difference. If the `source` sequence fails, the `Concat` operator waits until the currently subscribed subsequence completes before propagating the error. On the contrary the `Merge(1)` disposes immediately the subscription to the currently subscribed subsequence. Here is a minimal demonstration of this behavior:
```C#
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
var sequence = Observable
.Create(async (observer, ct) =>
{
observer.OnNext(1);
observer.OnNext(2);
await Task.Delay(500, ct);
observer.OnError(new Exception());
})
.Select(x => Observable.FromAsync(async (ct) =>
{
Console.WriteLine($"Item {x} started");
try { await Task.Delay(1000, ct); }
catch (OperationCanceledException) { Console.WriteLine($"Item {x} aborted"); throw; }
Console.WriteLine($"Item {x} finished");
return x;
}))
.Concat()
//.Merge(1)
.Do(x => Console.WriteLine($"Received: {x}"));
try { await sequence.DefaultIfEmpty(); }
catch (Exception ex) { Console.WriteLine($"Await failed ({ex.Message})"); }
await Task.Delay(200);
}
}
```
Output with `Concat`:
```none
Item 1 started
Item 1 finished
Received: 1
Await failed (Exception of type 'System.Exception' was thrown.)
```
Output with `Merge(1)`:
```none
Item 1 started
Await failed (Exception of type 'System.Exception' was thrown.)
Item 1 aborted
```
[Try it on Fiddle](https://dotnetfiddle.net/LukIwd).
I would like to ask if this difference in behavior between the two operators is by design.
Contributor guide
No contributing guide indexed for this repository
Research direction
Run the minimal C# reproduction in the issue and compare the logged behavior of Concat with Merge(1), focusing on source errors and cancellation of the active subsequence. Check the operator implementations and existing tests for these error and disposal semantics; done means the behavior is either confirmed as intentional or a specific corrective change is agreed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- developer-experience
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100