내가 이해하는 한, TPL Dataflow는 .NET 프로그래머 용 Actor 프로그래밍 모델을 제공합니다 (이전에 사용 가능했던 타사 솔루션에 대해서는 언급하지 않았습니다). 액터 모델 자체는 각 액터가 지원할 수있는 세 가지 기본 작동 인 '전송', '생성'및 '생성'이 있음을 선언합니다. TPL Dataflow에서 '될'의미를 다루는 '올바른'방법은 무엇입니까?TPL Dataflow : '의미있는 (Become)'의미
static void TestBecome()
{
TransformBlock<string, string> dispatcher = null;
dispatcher = new TransformBlock<string, string>
(
val =>
{
Console.WriteLine("Received for processing {0}", val);
switch (val)
{
case "CREATE": // create linked node
{
dispatcher.LinkTo(CreateNewNode().Item2);
break;
}
case "BECOME": // transform the node ('become' semantics)
{
var newNode = CreateNewNode();
Console.WriteLine("Dispatcher transformed to {0}", newNode.Item1);
dispatcher = newNode.Item2;
break;
}
default: return val; // dispatch the value to linked node (one of)
}
return string.Empty; // 'empty unit'
}
);
dispatcher.SendAsync("CREATE").ContinueWith(res => Console.WriteLine("Send CREATE: {0}", res.Result));
dispatcher.SendAsync("CREATE").ContinueWith(res => Console.WriteLine("Send CREATE: {0}", res.Result));
dispatcher.SendAsync("msg1").ContinueWith(res => Console.WriteLine("Send msg1: {0}", res.Result));
dispatcher.SendAsync("msg2").ContinueWith(res => Console.WriteLine("Send msg2: {0}", res.Result)); ;
Thread.Sleep(1000);
dispatcher.SendAsync("BECOME").ContinueWith(res => Console.WriteLine("Send BECOME: {0}", res.Result)); ;
Thread.Sleep(1000);
dispatcher.SendAsync("msg3").ContinueWith(res => Console.WriteLine("Send msg3: {0}", res.Result));
dispatcher.SendAsync("msg4").ContinueWith(res => Console.WriteLine("Send msg4: {0}", res.Result));
dispatcher.SendAsync("msg5").ContinueWith(res => Console.WriteLine("Send msg5: {0}", res.Result));
}
static Tuple<string, TransformBlock<string, string>> CreateNewNode()
{
var id = Guid.NewGuid().ToString("N");
var node = new TransformBlock<string, string>
(
val =>
{
if (string.IsNullOrWhiteSpace(val)) // pass trough 'empty unit'
return val;
Console.WriteLine("NODE {0}: {1}", id, val);
return val;
}
, new ExecutionDataflowBlockOptions { BoundedCapacity = 3 }
);
return Tuple.Create(id, node);
}
나는 서투른 '가'같은 방법을 찾을 :
은 다음 예제를 고려하십시오 대신 배우의 동작을 변경, 나는이 (원하지 않는 효과로 이어질 수있는) 그는 배우 인스턴스 자체를 변경합니다. '옳은'길은 무엇입니까?다른 한 가지 질문 : 표준 TDF 블록은 링크 된 노트 (예 : ActionBlock)에 메시지를 전달하지 않습니다. 그렇지 않으면 로직이 수동으로 작성되지 않습니다. (대다수의 블록). 메시지가 어떤 경우에만 (항상은 아님) 보내질 때 논리가 사용자 정의 블록으로 구현되어야한다는 논리가 맞습니까?
답변 해 주셔서 감사합니다. 나는 두 가지의 추가 질문을 던졌다 : 1) '블록이 병렬로 실행될 수 있다면, 당신은 ..'- 내부 대기열에서 처리하기 위해 작업을 하나씩 취하는 배우의 특성이 아니므로 전역 공유 상태가 존재하지 않으면 경쟁 조건이 불가능합니다. 즉, 캡처 된 상태 변수가 액터 당 하나 인 경우)? 2) TDF가 70 년대에서 80 년대에 발명 된 '학술적'배우 모델에 더 가깝게 접근해야 하는가, 아니면 실질적인 목표를 따르므로 그 역할이 훌륭 할까? –
1.'MaxDegreeOfParallelism'을 1이 아닌 값으로 설정하지 않는 이상입니다. 따라서 특정 블록 안에서 병렬 처리를하지 않으면 걱정할 필요가 없습니다. 2. 나에게 TDF에서의 방식은 의미가있다. 그러나 저는 다른 배우 모델 라이브러리 나 언어를 사용하지 않았습니다. – svick