BufferBlock<int> bb = new();
ActionBlock<int> ab = new(i=>{Console.Write("a" + i);throw new();}); //에러발생 타겟블록

var obb = bb.AsObservable(); //소스블록은 관찰가능하게 만들수 있다.
var ob = ab.AsObserver(); //타겟블록은 관찰자가 될수 있다.
class opc : IObserver<int> //별도로 구현할 수도 있다.
{
    public void OnCompleted()    {    }
    public void (Exception error)    {    }
    public void OnNext(int v) => Console.Write("o"+v);
}

bb.LinkTo(ab);
var d = obb.Subscribe(new opc());
obb.Subscribe(ob); //관찰자화된 불럭이 무효화되어도 Link처럼 관찰이 자동으로 무효화 되진 않았다. 리턴참고

await Task.Delay(100);
bb.Post(1);
bb.Post(2);
await Task.Delay(100); //연결블록이 없거나 에러등의 이유로 무효화되면 관찰할 수 있게된다.
bb.Post(3);
bb.Post(4);
bb.Post(5);
await Task.Delay(100); //모든 구독자의 관찰이 끝나면 소스는 소모된다.
d.Dispose();
await Task.Delay(100);
bb.Post(6);
bb.Post(7);
bb.Post(8);
await Task.Delay(100); //링크도 관찰자도 없으면 소스는 소모되지 않는다.

bb.Count


블록간의 링크는 여러 소스가 같은 타겟으로 연결할 수는 있으나, 한 소스에서 여러 타겟으로 연결할 수 없다.

위 예시처럼 여러개를 연결하면, 에러가 나지는 않고 늦게 한 연결은 앞의 연결이 해제된 후의 다음 연결로써 큐잉된다. 


블럭에 연결이 생기면 관찰할수 없게되고, 연결이 없어도 관찰이 있는것만으로도 소스의 소모가 발생한다.

개인적으로 연결과 관찰이 서로 무관하게 동작하는 쪽이 좋았겠다만, dotnet7 기준에서는 별다른 방법 없는듯 하다.


완료된 블럭관찰자를 추가하니 버퍼가 모두 소모되는걸로 미루어보아

블럭이 완료됨으로 인해 링크가 무효화되는것과 다르게, 블럭의 완료를 관찰의 완료로써 처리하지는 않는듯 하다.


Dataflowblock을 처음 봤을때부터 비동기요청의 동기화 뿐만 아니라 mqtt처럼 임의 클라이언트들에게 제공하는 데이터의 실시간 갱신을 serverside에서 처리시킬 용도써 구상했는데, 블럭의 링크만 가지고는 아무런 의미가 없고, 데이터플로우를 단방향이 아닌 이벤트처럼 확산시키기 위해 검색하면 BroadcastBlock만 나오고 이를 옵저버로 연계하는 방법에 대해선 알아내지 못해 사용하지 못하고 있었다.

손이 많이가고 안전성을 신뢰할수 없는 event 같은거보다 훨씬 안전하고 우아할듯 하다.