Skip to content

Commit

Permalink
change readme
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Jul 17, 2024
1 parent c3714c5 commit db5f3f4
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 36 deletions.
26 changes: 7 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -686,35 +686,23 @@ subject.Take(100).Count().Subscribe(x => Console.WriteLine(x));
Parallel.For(0, 1000, new ParallelOptions { MaxDegreeOfParallelism = 10 }, x => subject.OnNext(x));
```

This means that the issuance of OnNext must always be done on a single thread. Also, ReactiveProperty, which corresponds to BehaviorSubject in dotnet/reactive, is not thread-safe itself, so updating the value (set Value or call OnNext) must always be done on a single thread.

For converting external inputs into Observables, such as with FromEvent, and when the source of input issues in a multi-threaded manner, it is necessary to synchronize using `Synchronize` to construct the correct operator chain.

Of course, simply surrounding it with `lock` is also effective.
This means that the issuance of OnNext must always be done on a single thread. For converting external inputs into Observables, such as with `FromEvent`, and when the source of input issues in a multi-threaded manner, it is necessary to synchronize using `Synchronize` to construct the correct operator chain.

```csharp
lock(gate)
{
subject.OnNext(value);
}
subject.Synchronoize(gate).Take(100).Count().Subscribe();
```

Unlike other Subjects, ReactiveProperty's OnNext/Subscribe operations are not thread-safe. Therefore, when using it in a multi-threaded environment, both operations need to be locked.
In R3, ReplaySubject and BehaviorSubject do not require Synchronize and are thread-safe, including OnNext.

```csharp
lock(gate)
{
reactiveProperty.Value = value;
}
ReactiveProperty is not thread-safe and OnNext, set Value and Susbcribe cannot be called simultaneously. If you need to use it in such a situation, use `SynchronizedReactiveProperty` instead.

lock(gate)
```csharp
class MyClass
{
reactiveProperty.Subscribe(observer);
public SynchronizedReactiveProperty<int> Prop { get; } = new();
}
```

Regarding Dispose of subscription, it is thread-safe. Additionally, if it's not possible to lock ReactiveProperty itself, you can use `SubscribeOnSynchronize` to apply a lock during Subscribe operations within the operator.

Sampling Timing
---
The `Sample(TimeSpan)` in dotnet/reactive starts a timer in the background when subscribed to, and uses that interval for filtering. Additionally, the timer continues to run in the background indefinitely.
Expand Down
21 changes: 4 additions & 17 deletions sandbox/ConsoleApp1/Program.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
using R3;
using System.Diagnostics;

// https://github.com/Cysharp/R3/issues/232
var r1 = Observable.Return(1);
var r2 = Observable.Interval(TimeSpan.FromSeconds(1)).Index();

r1.Concat(r2).Subscribe(Console.WriteLine);

Observable.Concat(
Observable.Return("Start"),
SomeAsyncTask().ToObservable(),
Observable.Return("End")
).Subscribe(r =>
{
Console.WriteLine("Result:" + r);
});
await Task.Delay(TimeSpan.FromDays(1)); // wait


Console.ReadLine();

async ValueTask<string> SomeAsyncTask()
{
await Task.Delay(1000);
return "result";
}

0 comments on commit db5f3f4

Please sign in to comment.