2017-11-15 6 views
0

Rx .Net을 사용하여 일부 데이터를 파이프 라인으로 보내려고했지만 정말 어려움을 겪고 있습니다.Rx .Net을 사용하여 데이터 파이프 라인을 만들려고 시도합니다.

데이터가있는 저장되지 않은 Foos가 있습니다. Foos는 모음 모음을 만듭니다. 바가 저장된 후에 Bar에 BarId가 있으면 Foo의 데이터와 Bar의 BarId를 사용하여 Baz를 작성합니다. Foo의 Bars와 Baz가 모두 만들어지면 Foo의 데이터가 지워지고 Foo가 저장됩니다.

public class Base 
{ 
    public Guid Id { get; set; } = Guid.Empty; 

    public override string ToString() 
    { 
     return $"{GetType().Name}::Id:{Id}"; 
    } 

    public Task<Unit> Save() 
    { 
     Id = Guid.NewGuid(); 

     Console.WriteLine($"{ToString()} (save)"); 

     return Task.FromResult(Unit.Default); 
    } 
} 

public sealed class Foo : Base 
{ 
    public long FooId { get; } 

    public string Data { get; private set; } 

    public override string ToString() 
    { 
     return $"{base.ToString()},FooId:{FooId},Data:{Data ?? "NULL"}"; 
    } 

    public Task<Unit> ClearData() 
    { 
     Data = null; 

     return Task.FromResult(Unit.Default); 
    } 

    public Foo(long index) 
    { 
     FooId = index; 
     Data = $"Foo({index})"; 

     Console.WriteLine($"{ToString()} (ctor)"); 
    } 
} 

public class Map : Base 
{ 
    public int Index { get; } 

    public string Mapping { get; } 

    public Guid BarId { get; protected set; } = Guid.Empty; 

    public sealed override string ToString() 
    { 
     return $"{base.ToString()},Index:{Index},BarId:{BarId},Mapping:{Mapping}"; 
    } 

    protected Map(int index, string data, Func<string, string> mapper) 
    { 
     Mapping = mapper(data); 
     Index = index; 
    } 
} 

public sealed class Bar : Map 
{ 
    public Bar(int index, string data, Func<string, string> mapper) : base(index, data, mapper) 
    { 
     if (new Random().Next(3) > 0) 
     { 
      BarId = Guid.NewGuid(); 

      Console.WriteLine($"{ToString()} (ctor)"); 
     } 
    } 
} 

public sealed class Baz : Map 
{ 
    public Baz(int index, Guid barId, string data, Func<string, string> mapper) : base(index, data, mapper) 
    { 
     BarId = barId; 

     Console.WriteLine($"{ToString()} (ctor)"); 
    } 
} 

나는 여러 가지를 시도하지만,이 사람은 내가 내가 무엇을 찾고 있어요에 도착 가장 가까운 : 다음은 클래스는 그것은 바의 오른쪽 양을 생성

var foos = Observable.Interval(TimeSpan.FromSeconds(1)).Take(2).Select(i => new Foo(i)); 

var units = from foo in foos 
      let idxs = Observable.Range(1, 3) 
      from idx in idxs 
      let bar = new Bar(idx, foo.Data, s => $"{s}Bar") 
      from barSaved in bar.Save() 
      where bar.BarId != Guid.Empty 
      let baz = new Baz(idx, bar.BarId, foo.Data, s => $"{s}Baz") 
      from bazSaved in baz.Save() 
      from fooChanged in foo.ClearData() 
      from fooSaved in foo.Save() 
      select Unit.Default; 

units.Subscribe(); 

및 Baz는 저장하지만 저장 한 Baz가 생성 될 때마다 Foo를 저장하거나 Baz가 없으면 결코 저장하지 않습니다.

나는 누군가가 나를 도울 수 있기를 바라고, 아마도 패러다임에 대한 더 나은 이해를 돕는 Reactive Programming에 대해 새로운 것을 배울 것입니다.

편집 : 정적 인스턴스에 난수 제공자를 이동하려고

하지만 그것은 작동하지 않았다. 여기에 어떤 일이 발생하는지 보여줍니다 일부 출력입니다 :

Foo::Id:00000000-0000-0000-0000-000000000000,FooId:0,Data:Foo(0) (ctor) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:00000000-0000-0000-0000-000000000000,Mapping:Foo(0)Bar (ctor) 
Bar::Id:28789b8b-03d4-4160-97f2-b2cbafd80c73,Index:1,BarId:00000000-0000-0000-0000-000000000000,Mapping:Foo(0)Bar (save) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Bar (ctor) 
Bar::Id:d43d2e43-b812-4657-9e4f-a5b875a595fb,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Bar (save) 
Baz::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Baz (ctor) 
Baz::Id:fdf464d1-9240-49e4-89cd-dbab758159fc,Index:2,BarId:81e79b81-6692-406f-a025-448cd203cb73,Mapping:Foo(0)Baz (save) 
Foo::Id:04d9d819-26bc-41dc-8f1b-a0e509acd2e5,FooId:0,Data:NULL (save) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Bar (ctor) 
Bar::Id:6b82fc20-80ff-41bd-848d-a115f58392c4,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Bar (save) 
Baz::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Baz (ctor) 
Baz::Id:fa361c43-ee07-44cc-8628-4835fce6da9d,Index:3,BarId:6894c1f0-d776-496f-9da4-4f272a338f90,Mapping:Baz (save) 
Foo::Id:6f423cf5-8260-4d98-a0bc-4762893b5fe4,FooId:0,Data:NULL (save) 
Foo::Id:00000000-0000-0000-0000-000000000000,FooId:1,Data:Foo(1) (ctor) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Bar (ctor) 
Bar::Id:94f5842f-eb1c-4248-a70a-dac5eb843cc1,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Bar (save) 
Baz::Id:00000000-0000-0000-0000-000000000000,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Baz (ctor) 
Baz::Id:d46b1d7e-eda2-4c63-8810-830e3416e975,Index:1,BarId:5a79b126-27d8-43a1-9bb6-4d28394d5710,Mapping:Foo(1)Baz (save) 
Foo::Id:e198e636-bfd7-49c5-a260-346524ec4019,FooId:1,Data:NULL (save) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:2,BarId:00000000-0000-0000-0000-000000000000,Mapping:Bar (ctor) 
Bar::Id:206a8796-32da-493f-9582-7c551781e2d5,Index:2,BarId:00000000-0000-0000-0000-000000000000,Mapping:Bar (save) 
Bar::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Bar (ctor) 
Bar::Id:ffda6907-93b0-411f-aa40-3fee790b52cb,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Bar (save) 
Baz::Id:00000000-0000-0000-0000-000000000000,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Baz (ctor) 
Baz::Id:2071927f-27d6-4df6-a74f-1c0bdfbba8d5,Index:3,BarId:154481ad-33c3-49d7-af2b-3f7738f1f692,Mapping:Baz (save) 
Foo::Id:07460e6e-d3db-4ed8-a441-e16f06cd908a,FooId:1,Data:NULL (save) 

당신이 볼 수있는 것처럼, 바즈가 저장 될 때, 푸가 데이터를 지우고 모든 후속 바 만들고, 저장하고 Bazs 자신의 데이터가 손실은 - 자신의 매핑이 더있다 볼 Foo (색인).

편집 :

내가 달성하기 위해 노력하고있어 모든 만들어 저장되어왔다 푸의 바, Bazs 후에 만 ​​다음 푸의 데이터가 지워이며 수행 저장하는 것이있다.

추적을 포함하도록 편집 된 소스 코드.

+0

귀하의 코드는 추적 데이터를 출력하는 방법을 표시하지 않습니다. 출력물이 실제로 어떻게 생겼는지 함께 알려주시겠습니까? – Enigmativity

+0

"보시다시피, Baz가 저장되면 Foo는 데이터를 지우고 저장합니다. 이후의 모든 Bars 및 Baz가 데이터를 잃게됩니다."- 쿼리가 수행 할 의도가 아닌가? 'foo.ClearData()에서 fooChanged에서'줄은 Observable.Range (1, 3)의 다음 값이 오면'foo.Data'가'null' 일 때 데이터를 지 웁니다. – Enigmativity

+0

@Enigmativity 네, 그게 문제입니다. – Aaron

답변

2

고객님의 문제는 if (new Random().Next(3) > 0)입니다. Random 시스템 클럭의 개체 시드가 있으므로이 코드를 빠르게 연속해서 호출하면 동일한 값을 얻습니다. 다음과 같이 시도하십시오.

public sealed class Bar : Map 
{ 
    public static Random _rand = new Random(); 
    public Bar(int index, string data, Func<string, string> mapper) : base(index, data, mapper) 
    { 
     if (_rand.Next(3) > 0) 
     { 
      BarId = Guid.NewGuid(); 
     } 
    } 
} 

올바른 결과를 얻는 것처럼 보입니다.


나는 방법 밖에 Random 인스턴스를 유지 한 다음이를 시도 할 것입니다 :

var units = 
    from foo in foos 
    from inner in 
    (
     from idx in Observable.Range(1, 3) 
     let bar = new Bar(idx, foo.Data, s => $"{s}Bar") 
     from barSaved in bar.Save() 
     where bar.BarId != Guid.Empty 
     let baz = new Baz(idx, bar.BarId, foo.Data, s => $"{s}Baz") 
     from bazSaved in baz.Save() 
     select Unit.Default 
    ).ToArray() 
    from fooChanged in foo.ClearData() 
    from fooSaved in foo.Save() 
    select Unit.Default; 
+0

좋아요! 그거야. 감사.이제는 방금 작동해야합니다 * 왜 * 작동하여 배울 수 있습니다! – Aaron

+2

@Aaron - Go는'.ToArray()'연산자를 찾는다. – Enigmativity